Posts

....
Technical Blog for .NET Developers ©

Wednesday, May 29, 2013

Serialization

Serialization is the act of taking an in-memory object or object graph (set of objects that reference each other) and flattening it into a stream of bytes or XML nodes that can be stored or transmitted. Deserialization works in reverse, taking a data stream and re-building it into an in-memory object or object graph

Serialization and deserialization are mostly used with two objectives:

- Transmit objects across a network or application boundary

- Store representations of objects within a file or database


The three main engines in .NET framework for serialization are the next:

- The data contract serializer

- The binary serializer

- The XML serializer


There is also the IXMLSerializable interface, used to implement own code serialization, using XmlReader and XmlWriter

The data contract serializer is the newest and the most versatile of the three serialization engines and is used by WCF

In this example, we will expose how to use the data contract serializer

There are two ways of using this serializer, through DataContractSerializer class, or through NetDataContractSerializer class. NetDataContractSerializerClass tightly types to data contract types, it relies on the presence of a specific .NET type in a specific namespace and assembly in order to deserialize

If you’re saving an object graph to a “black box", you can choose either serializer, depending on what benefits are more important to you. If you’re communicating through WCF, or reading/writing an XML file, it's highly recommended the DataContractSerializer

This is the class to serialize, and the code to serialize/deserialize

     
	namespace Serialization
    {
        [DataContract]
        public class City
        {
            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public int Cityzens { get; set; }
        }
    }
    

     
	City ciudad = new City() { Name = "Barcelona", Cityzens = 1620940 };

    var ds = new DataContractSerializer(typeof (City));

    // Serialize
    using (Stream stream = File.Create("barcelona.xml"))
        ds.WriteObject(stream, ciudad);
 
    // Deserialize
    City bcn;
    using (Stream stream = File.OpenRead("barcelona.xml"))
        bcn = (City)ds.ReadObject(stream);

    Console.WriteLine("{0}: {1}", bcn.Name, bcn.Cityzens);
    

The result of the previous code is the next


<City xmlns="http://schemas.datacontract.org/2004/07/Serialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Cityzens>1620940</Cityzens><Name>Barcelona</Name></City>

DataContractSerializer, and NetDataContractSerializer, both use the XmlFormatter by default, with an XmlWriter, you can request that the xml be intended for readability

     
	City ciudad = new City() { Name = "Barcelona", Cityzens = 1620940 };

    var ds = new DataContractSerializer(typeof (City));

    XmlWriterSettings setts = new XmlWriterSettings() { Indent = true };

    using (XmlWriter writer = XmlWriter.Create("city.xml", setts))
        ds.WriteObject(writer, ciudad);

    System.Diagnostics.Process.Start("city.xml");
    

The result of the previous code is as follows



The XML element name reflects the data contract name, which, by default, is the .NET type name; the XML namespace reflects the data contract namespace, which, by default, is http://schemas.datacontract.org/2004/07/, plus the .NET type namespace. You can override both of them in this way


     
	[DataContract (Name="Ciudad", Namespace="http://innovar.com")]
    public class City
    {
        [DataMember (Name="Nombre")]
        public string Name { get; set; }

        [DataMember (Name="Poblacion")]
        public int Cityzens { get; set; }
    }
    




<METHOD SOFTWARE © 2013>