Pages

Search This Blog

Wednesday, February 11, 2015

Serialization In C#

Serialization In C#
Serialization/De-serialization is a very important feature of an application, especially when it needs to communicate with another application by sending and receiving data. Because, generally, two different applications (also may be of different platforms) can’t understand one another one’s internal data structure. In which case, XML data (Extensible Markup Language) can be a good bearer to make the communication between them easier. So, now comes the requirement to creation of the XML data and constructing/retrieving data to/from XML. Although, it’s possible to create the XML file manually with own defined tag and manipulate them with LINQ to XML or so, there is a great and more efficient/quick solution from .NET for this purpose, where we can serialize/de-serialize a .NET class (here c# class) very easily without worrying that much.
In this blog, I am going to show you how to do xml serialization with c# code examples. Here I will be reading and writing a settings class. If you need similar settings class and read/write that from your application, then you can re-use the complete class that i am going to put at the end of the post.

 

Serialize A C# Class To XML File:

For performing a complete XML serialization of c# class and save it to a physical XML file, we will need help of 2 different types of .NET classes.
One is System.Xml.Serialization.XmlSerializer class (same class will be needed in De-serialization, so better importing the System.Xml.Serialization name space at the top of the class page.).
Another is System.IO.StreamWriter (corresponding reader class will be used on De-serialization, both are under common name space System.IO). XmlSerializer instance will do the main task of serialization and ‘StreamWriter’object will write the resultant serialized XML to a given file. Following are the code snippet for accomplish this:
string path = "MySettings.xml";
XmlSerializer x = new XmlSerializer(settings.GetType());
StreamWriter writer = new StreamWriter(path);
x.Serialize(writer, settings);


See it’s very simple isn’t it? We just have to call the ‘Serialize’ method with parameters of the writer and object to serialize. Just for your information, you can also use other type of write classes (such as ‘TextWriter’) also instead of ‘StreamWriter’ , checkout the available overloaded methods of the ‘Serialize’ function for more details.
After the serialization completes, you will see a XML file named ‘MySettings.xml’ in the debug directory (as it’s treated as the current directory by the application). Let’s Assume we are using a settings class that we are creating a XML file of, is as like following code sample:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyApplication.Config
{
    public class MySettings
    {
        #region Properties
         
        /// <summary>
        /// get/set the property 1
        /// </summary>
        private string property1= "";       
        public string Property1
        {
            get
            {
                return property1;
            }
            set
            {
                property1= value;
            }
        }

        /// <summary>
        /// get/set property 2
        /// </summary>
        private string property2= "";
        public string Property2
        {
            get
            {
                return property2;
            }
            set
            {
                property2= value;
            }
        }

        #endregion

        public MySettings()
        {
        }
    }
}

For the class like above, the resultant XML file should contains texts as like follows:
<?xml version="1.0" encoding="utf-8"?>
  <Property1>Property1 Value</Property1>
  <Property2>Property2 Value</Property2>
</MySettings>


De-Serialize A XML File To C# Class:

This is also almost similar as the serialization. This time, we will be using two classes, XmlSerializer and StreamReader (instead of StreamWriter). Here is the sample code to accomplish this:
MySettings settings = new MySettings();
string path = "MySettings.xml";
XmlSerializer x = new XmlSerializer(typeof(MySettings));
StreamReader reader = new StreamReader(path);
settings = (TVSettings)x.Deserialize(reader);


Notice that, we have to pass the type of object we are trying to De-serialize (as well as serialize), so you must have to know the type of object that will be created from the XML file.

Custom XML Serialization/De-serializer Class:

Here is the code block of a complete custom class that will read/write XML file from/to c# classes:
public class SettingsManager
    {
        /// <summary>
        /// Write Configuration To XML File
        /// </summary>
        /// <param name="settings"></param>
        /// <returns></returns>
        public static bool Write(MySettings settings,string path)
        {
            try
            {
                XmlSerializer x = new XmlSerializer(settings.GetType());
                StreamWriter writer = new StreamWriter(path);
                x.Serialize(writer, settings);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Read Settings
        /// </summary>
        /// <returns></returns>
        public static MySettings Read()
        {           
            TVSettings settings = new MySettings(string path);
            try
            {
                XmlSerializer x = new XmlSerializer(typeof(MySettings));
                StreamReader reader = new StreamReader(path);
                settings = (TVSettings)x.Deserialize(reader);
                return settings;
            }
            catch
            {
                return settings;
            }
        }
    }


Purpose Of ISerializable Interface In Serialization:

You will notice that, we haven’t implemented any ISerializable interface or use any ‘Serializable’/’NonSerializable’ attribute. If we can do without them, why they exist in .NET? Ans is, of course it has quite significance. There are several points to consider regarding this matter:
·         Extending ISerializable interface is required in the cases where .NET objects need to control their own serialization and De-serialization. And also, its used to provide custom binary serialization, usually for ‘BinaryFormatter’.
·         What we just practiced, XmlSerialization, only use properties for the process, ISerializable isn’t required here as XMLSerializer can take care of it very well.
But still, its always best to extend the classes from this and mark ‘NonSerialized’ for which serialization won’t use for.

XML Serialization with IXMLSerializable:




If you are writing a class that will need majorly for XML serialization, you can also follow another simple procedure then described above. Simply, just implement IXMLSerializable interface. Then you will need to implement 3 methods which will be as like following code example:


public System.Xml.Schema.XmlSchema GetSchema()
{
    throw new NotImplementedException();
}

public void ReadXml(System.Xml.XmlReader reader)
{
    throw new NotImplementedException();
}

public void WriteXml(System.Xml.XmlWriter writer)
{
    throw new NotImplementedException();
}

You just need to pass the write/reader (XMLReader/XMLWrite) as parameter to do the read/write operation.


No comments:

Post a Comment