Object serialization is the process of converting an object to a format that is suitable for persistence (database, file, etc) or transportation (remoting, Web Services, MSMQ, etc).
The format of the output byte stream is governed by a formatter object. When you serialize data, you construct a formatter object that implements the required format.
With .NET Framework 2.0 and above you can use two formatters: BinaryFormatter and SoapFormatter. You can also serialize objects (well, just the public members, not the private ones - which is know as shallow serialization) by using the XMLSerializer class.
The following class Person implements some attributes that are used in the process of seralization. This class is also used on the application example you can download below.
[Serializable] //<-- This atribute is just required by BinaryFormatter and SoapFormatter public class Person //<-- XMLSerializer needs that the class is defined as public { //[System.Xml.Serialization.XmlIgnore] //<-- using this attribute, this field will be ignored in Xml Serialization public string FirstName; //Some few public properties to serialize. They will be serialize by the three formatters. public string LastName; [NonSerialized] //<-- Using this attribute, the field Nationality won't be serialized (by any of the three serializers) public string Nationality; private string _Address; //this private field won't be serialized using XmlSerialization. They will be serialized using Binary or Soap formatters private string _ZIPCode; //this private field won't be serialized using XmlSerialization. They will be serialized using Binary or Soap formatters //let's create a method to set the private properties. public void SetAddress(string address, string zipCode) { _Address = address; _ZIPCode = zipCode; } public override string ToString() { return string.Format("I'm {0} {1} from {2}!. Address: {3}, {4}", FirstName,LastName,Nationality, _Address,_ZIPCode); } }
PROS
CONS
BinaryFormatter serialization use example
Person p=new Person(); string path=@"c:\myfile.bin"; using (System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write)) { System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); b.Serialize(fs, p); fs.Close(); }
This code will serialize object p (type Person) on file c:\myfile.bin with binary format
BinaryFormatter deserialization use example:
string path=@"c:\myfile.bin"; using (System.IO.FileStream ds = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); Person p = bf.Deserialize(ds) as Person; }
This code will deserialize object p (type Person) from c:\myfile.bin
SoapFormatter serialization use example:
Person p=new Person(); string path=@"c:\myfile.soap"; using (System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write)) { System.Runtime.Serialization.Formatters.Soap.SoapFormatter f = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter(); f.Serialize(fs, p); fs.Close(); }
This code will serialize object p (type Person) on file c:\myfile.soap with Soap format
SoapFormatter deserialization use example:
string path=@"c:\myfile.soap"; using (System.IO.FileStream ds = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { System.Runtime.Serialization.Formatters.Soap.SoapFormatter sf = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter(); Person p = sf.Deserialize(ds) as Person; AppendToLog(string.Format("Single person deserialized from {0} in SOAP format: {1}", path, p)); }
This code will deserialize object p (type Person) from file on c:\myfile.soap using Soap formatter
A Person object after Soap serialization looks like this:
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <a1:Person id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Serialization/dotneat_net.Serialization%2C%20Version%3D0.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull"> <FirstName id="ref-3">Joe</FirstName> <LastName id="ref-4">Doe</LastName> <_Address id="ref-5">dotneat.net Street, Zaragoza, Spain</_Address> <_ZIPCode id="ref-6">50007</_ZIPCode> </a1:Person> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
XmlSerializer serialization use example:
Person p=new Person(); string path=@"c:\myfile.xml"; System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Person)); using (System.IO.FileStream xmlStream = new System.IO.FileStream(path, System.IO.FileMode.Create, System.IO.FileAccess.Write)) { serializer.Serialize(xmlStream, p); xmlStream.Close(); }
This code will serialize object p (type Person) on file on c:\myfile.xml using the XmlSerializer class
XmlSerializer deserialization use example:
string path=@"c:\myfile.xml"; System.Xml.Serialization.XmlSerializer dxml = new System.Xml.Serialization.XmlSerializer(typeof(Person)); using (System.IO.FileStream xmlStream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { Person p = dxml.Deserialize(xmlStream) as Person; xmlStream.Close(); }
This code will deserialize object p (type Person) from file c:\myfile.xml using the XmlSerializer class
A Person object after XML serialization looks like this (see how just public members are serialized):
<?xml version="1.0"?> <Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <FirstName>Joe</FirstName> <LastName>Doe</LastName> </Person>
As you may see, private members are not serialized.
You can omit fields from being serialized by marking them with the [NonSerialized] attribute (see Nationality field in Person class).
If you are required to, you can modify the way the data in objects is serialized and deserialized. For example, you may want to serialize the account number and pass code of the class BackAccount crypted (just those two fields)
You need to implement the interface ISerializable on the class to serialize. If the type implements ISerializable interface, the formatter calls the GetObjectData to convert the object into the stream of bytes.
Use OnSerializingAttribute and OnSerializedAttribute to mark methods that will be executed before and after the serialization takes place.
[Serializable] public class Person : ISerializable{ ..... [OnSerializing] public void Deserializing (StreamingContext context){ //before serialization } [OnSerialized] public void Serialized (StreamingContext context){ //after serialization } }
It is also possible to control how the deserialization process by implementing a constructor that takes a SerializationInfo and a StreamingContext as parameters.
[Serializable] public class Person : ISerializable{ //Deserialization constructor private Person(SerializationInfo info, StreamingContext context){ string fname=info.GetString("FirstName"); // ... } }
Use OnDeserializingAttribute and OnDeserializedAttribute to specify methods to run before and after the object is deserialized.
[Serializable] public class Person : ISerializable{ ..... [OnDeserializing] public void Deserializing (StreamingContext context){ //before deserialization } [OnDeserialized] public void Deserialized (StreamingContext context){ //after deserialization } }
Serialization application example source code (hosted on google code)
You can use the application for serialize/deserialize a simple example class "Person". You can go and check file size and format of output file. You can also serialize/deserilize non generic (ArrayList) and generic (List) collections of Person, so you can see how the formatters serialize those types.
Performance
There is a performance test functionality. You can check which is the faster way of serializing a simple type. Feel free to extend the example to create performance tests that suits your needs
Remember Me
a@href@title, b, em, i, strike, strong