User Tools

Site Tools


notes:csharp:serialization

Serialization in .NET

Serialization is the process of transforming an in-memory object or object graph into a stream of bytes or text. Deserialization is the opposite. .NET classes that support serialization can be found in the System.Runtime.Serialization and System.Xml.Serialization namespaces.

Two the most popular .NET serialization technologies are:

  • DataContractSerializer
  • DataContractJsonSerializer

.NET serialization mechanisms:

  • Data contract serializers: DataContractSerializer (WCF) and DataContractJsonSerializer (JSON)
  • XmlSerializer - XML serialization (attribute-based)
  • BinaryFormatter - binary serialization
  • The IXmlSerializable interface for complex tasks
Mechanism Output Serialized members Class attribute
DataContractSerializer XML or JSON public and private [DataContract], [DataMember]
XmlSerializer XML public only [Serializable]
BinaryFormatter binary public and private [Serializable]

DataContractSerializer

Example: Serialize and deserialize an instance of a Person class using DataContractSerializer:

using System.IO;
using System.Runtime.Serialization;
...
static void Main(string[] args)
{
    Person p = new Person { Name = "Leopold Makuta" };
 
    DataContractSerializer ser = new DataContractSerializer(typeof(Person));
 
    // Serialize
    using (Stream stream = new FileStream("data.xml", FileMode.Create))
    {
        ser.WriteObject(stream, p);
    }
 
    // Deserialize
    using (Stream stream = new FileStream("data.xml", FileMode.Open))
    {
        Person result = (Person)ser.ReadObject(stream);
    }
}
...
[DataContract]
public class Person
{
    [DataMember] private Guid ID { get; set; }
    [DataMember] public string Name { get; set; }
 
    public Person() { ID = Guid.NewGuid(); }
}

DataContractJsonSerializer

Example: Serialize and deserialize an instance of a Person class using DataContractJsonSerializer:

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
...
static void Main(string[] args)
{
    Person p = new Person { Name = "Leopold Makuta" };
 
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
 
    using (MemoryStream stream = new MemoryStream())
    {
        // Serialize
        ser.WriteObject(stream, p);
 
        stream.Position = 0;
        StreamReader reader = new StreamReader(stream);
        Console.WriteLine(reader.ReadToEnd()); 
            // displays: {"ID":"4740087d-2bca-491e-a668-4acf5c731cbd","Name":"Leopold Makuta"}
 
        // Deserialize
        stream.Position = 0;
        Person result = (Person)ser.ReadObject(stream);
    }
}
...
[DataContract]
public class Person
{
    [DataMember] private Guid ID { get; set; }
    [DataMember] public string Name { get; set; }
 
    public Person() { ID = Guid.NewGuid(); }
}

XmlSerializer

Example: A generic method to deserialize an XML string to an object:

public T FromXml<T>(string xml)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    T value;
    using (StringReader reader = new StringReader(xml))
    {
        object deserialized = serializer.Deserialize(reader);
        value = (T)deserialized;
    }
 
    return value;
}
 
// Usage
IEnumerable<Book> list = FromXml<List<Book>>(xml);

Example: A generic method to serialize an object to an XML string:

public string ToXml<T>(T value)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    StringBuilder sb = new StringBuilder();
    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Indent = true,
        OmitXmlDeclaration = true,
    };
 
    using (XmlWriter writer = XmlWriter.Create(sb, settings))
    {
        serializer.Serialize(writer, value);
    }
    return sb.ToString();
}
 
// Usage
List<Book> books = GetBooks();
string xml = ToXml<List<Book>>(books);

Example: Serialize and deserialize an instance of a Person class using XmlSerializer:

using System.IO;
using System.Xml.Serialization;
...
static void Main(string[] args)
{
    Person p = new Person { Name = "Leopold Makuta" };
 
    // Serialize.
    string xml;
    XmlSerializer ser = new XmlSerializer(typeof(Person));
    using (StringWriter writer = new StringWriter())
    {
        ser.Serialize(writer, p);
        xml = writer.ToString();
    }
 
    // Deserialize.
    using (StringReader reader = new StringReader(xml))
    {
        Person p2 = (Person)ser.Deserialize(reader); // p2.ID != p.ID
        // ...
    }
}
...
[Serializable]
public class Person
{
    private Guid ID { get; set; } // private fields are not serialized
    public string Name { get; set; }
 
    // The default ctor is required for XMLSerializer.
    public Person() { ID = Guid.NewGuid(); }
}

Example: Serialize a collection of book objects using XmlSerializer:

using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
...
static void Main(string[] args2)
{
    List<Book> books = new List<Book>();
    books.Add(new Book { ID = 1, Title = "Modern C++" });
    books.Add(new Book { ID = 2, Title = "DirectX in 7 Days" });
    books.Add(new Book { ID = 3, Title = "Programming in Java" });
 
    Library library = new Library();
    library.Books = books;
 
    XmlSerializer serializer = new XmlSerializer(typeof(Library));
    using (StreamWriter writer = new StreamWriter("books.xml"))
    {
        serializer.Serialize(writer, library);
    }
}
...
public class Book
{
    [XmlAttribute]
    public int ID { get; set; }
 
    [XmlElement("Name")]
    public string Title { get; set; }
 
    [XmlIgnore]
    public Book isKindle { get; set; }
}
 
public class Library
{
    [XmlArray("Items")]
    [XmlArrayItem("Item")]
    public List<Book> Books { get; set; }
}

Output (books.xml):

<?xml version="1.0" encoding="utf-8"?>
<Library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Items>
    <Item ID="1">
      <Name>Modern C++</Name>
    </Item>
    <Item ID="2">
      <Name>DirectX in 7 Days</Name>
    </Item>
    <Item ID="3">
      <Name>Programming in Java</Name>
    </Item>
  </Items>
</Library>

Example: Deserialize from a string containing XML to an object using XmlSerializer:

using System.IO;
using System.Xml.Serialization;
...
public static void Main()
{
    string xml = 
        @"<?xml version=""1.0"" encoding=""utf-8""?>
          <Person xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
                  xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
              <FirstName>Leon</FirstName>
              <LastName>McBeret</LastName>
          </Person>";
 
    XmlSerializer ser = new XmlSerializer(typeof(Person));
    Person p = (Person)ser.Deserialize(new StringReader(xml));
    // ...
}
...
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

BinaryFormatter

Example: Serialize and deserialize an instance of a Person class using BinaryFormatter:

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
...
static void Main(string[] args)
{
    Person p = new Person { Name = "Leopold Makuta" };
 
    IFormatter formatter = new BinaryFormatter();
 
    // Serialize.
    using (Stream stream = new FileStream("data.bin", FileMode.Create))
    {
        formatter.Serialize(stream, p);
    }
 
    // Deserialize.
    using (Stream stream = new FileStream("data.bin", FileMode.Open))
    {
        Person p2 = (Person)formatter.Deserialize(stream);
        // ...
    }
 
    // Compress and serialize.
    using (Stream s = File.Create("data.bin")) // FileStream
    using (GZipStream ds = new GZipStream(s, CompressionMode.Compress))
        formatter.Serialize(ds, person);
 
     // Decompress and deserialize.
    using (Stream s = File.OpenRead("data.bin")) // FileStream
    using (GZipStream ds = new GZipStream(s, CompressionMode.Decompress))
    {
        Book book2 = formatter.Deserialize(ds) as Book;
    }    
}
...
[Serializable]
public class Person
{
    private Guid ID { get; set; }
    public string Name { get; set; }
 
    public Person() { ID = Guid.NewGuid(); }
}

SoapFormatter

Example: Serialize and deserialize an instance of a Person class using SoapFormatter:

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
...
static void Main(string[] args)
{
    Person p = new Person { Name = "Leopold Makuta" };
 
    IFormatter formatter = new SoapFormatter();
 
    // Serialize.
    using (Stream stream = new FileStream("data.xml", FileMode.Create))
    {
        formatter.Serialize(stream, p);
    }
 
    // Deserialize.
    using (Stream stream = new FileStream("data.xml", FileMode.Open))
    {
        Person p2 = (Person)formatter.Deserialize(stream);
        // ...
    }
}
...
[Serializable]
public class Person
{
    private Guid ID { get; set; }
    public string Name { get; set; }
 
    public Person() { ID = Guid.NewGuid(); }
}

ISerializable

Example: An example of a class implementing the ISerializable interface:

using System.Runtime.Serialization;
using System.Security.Permissions; // SecurityPermission
...
[Serializable]
public class Person : ISerializable
{
    public int ID { get; set; }
    public string Name { get; set; }
    private bool isUpdated = false;
 
    public Person() { }
 
    protected Person(SerializationInfo info, StreamingContext context)
    {
        // Here we could implement security checks to make sure
        // nobody tampered with data. 
        ID = info.GetInt32("Value1");
        Name = info.GetString("Value2");
        isUpdated = info.GetBoolean("Value3");
    }
 
    [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Value1", ID);
        info.AddValue("Value2", Name);
        info.AddValue("Value3", isUpdated);
    }
}
notes/csharp/serialization.txt · Last modified: 2016/12/14 by admin