Website development and design blog, tutorials and inspiration

XML Serialization and Deserialization

XML Serialization and Deserialization for Dummies

By , 15th August 2008 in C#

Serialization is the process of saving class member data into an XML document which can be transmitted over the internet or saved to a text file. Deserialization is the reverse process - loading class member data from an XML document.
 

Only public classes and public properties and fields can be serialised - methods and private members are not serialised and cannot be deserialized. Private classes cannot be serialised and will result in a compilation error.

When you serialise to XML, the resulting file can be used to transmit data across the Internet via web services (a web service project will automatically serialise a class without your knowledge and deserialize it back into a class at the other end). It can also be used to save custom user or application preferences, saving the state of an application when it is closed or export data for other programs or archiving.

Let's start off with a simple test class comprising of a couple of public fields, private fields and a method. For the purposes of this example fields have not been encapsulated in order to keep the code simple.

  1. public class myTestClass
  2. {
  3. public string myString = "Hello World";
  4. public int myInt = 1234;
  5. public string[] myArray = new string[4];
  6. private int myPrivateInt = 4321;
  7.  
  8. public string myMethod()
  9. {
  10. return "Hello World";
  11. }
  12. }

If you just have a simple class with a default constructor (no parameters) and you do not want to control serialisation then you need not do anything special. If on the other hand your class does not have a parameterless constructor, or you need to control how serialisation is performed then you will need to implement the ISerializable interface.

For this tutorial, we will assume that you are using a simple class since 9 times out of 10 this is what you will be doing. We will cover ISerializable in a later tutorial.

We can create some simple code to convert the class above into an XML document using a XmlSerializer class and a StreamWriter.

  1. class Program
  2. {
  3. static void Main()
  4. {
  5. // create new object and populate test data
  6. myTestClass test = new myTestClass();
  7. test.myArray[0] = "qwerty";
  8. test.myArray[1] = "asdfgh";
  9. test.myArray[2] = "zxcvbn";
  10. test.myArray[3] = "123456";
  11.  
  12. // these lines do the actual serialization
  13. XmlSerializer mySerializer = new XmlSerializer(typeof(myTestClass));
  14. StreamWriter myWriter = new StreamWriter("c:/myTestClass.xml");
  15. mySerializer.Serialize(myWriter, test);
  16. myWriter.Close();
  17. }
  18. }

In this example, the first line creates a XmlSerializer using the typeof method to create a serialize specific to the myTestClass class. We then create a StreamWriter pointing to an XML file on the C drive. Finally, we call the Serialize method of the Serializer passing in the parameters for the writer and the object itself. Finally, we close the writer stream.

This will result in an xml file like this:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <myTestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  3. <myString>Hello World</myString>
  4. <myInt>1234</myInt>
  5. <myArray>
  6. <string>qwerty</string>
  7. <string>asdfgh</string>
  8. <string>zxcvbn</string>
  9. <string>123456</string>
  10. </myArray>
  11. </myTestClass>

Deserialization

Deserialization is the reverse process. We will load in an XML document, pass the data to the deserializer and produce an instance of the class populated with the data.

  1. static void Main()
  2. {
  3. myTestClass test;
  4.  
  5. XmlSerializer mySerializer = new XmlSerializer(typeof(myTestClass));
  6. FileStream myFileStream = new FileStream("c:/mtTestClass.xml",FileMode.Open);
  7.  
  8. test = (myTestClass)mySerializer.Deserialize(myFileStream);
  9. }

You need to cast the Deserialize result into the correct class for the data being received since it will by default return an object.

If you are working with ASP.Net and you are using any other than in process state management (InProc) such as State Server or SQL Server, then you will need to mark each of the classes to be serialised as "Serializable" to prevent errors. Again you can implement the ISerializable interface as well if you wish.

  1. Session["sessionTest"] = test;

When using the above code to add an instance of myTestClass to the ASP.Net session cache (which is configured to state server or Sql server) the CLR will raise a runtime SerializationException :

Type 'myTestClass' in Assembly App_Code.nrkp4p10, Version=0.0.0.0, Culture=neutral,PublicKeyToken=null" is not marked as serializable.

This exception can be avoided by adding the class attribute Serializable to the declaration.

  1. [Serializable]
  2. public class myTestClass
  3. {
  4. public string myString = "Hello World";
  5. public int myInt = 1234;
  6. public string[] myArray = new string[4];
  7. private int myPrivateInt = 4321;
  8.  
  9. public string myMethod()
  10. {
  11. return "Hello World";
  12. }
  13. }

You can now add this class to the cache where it will be automatically serialised and deserialized when needed.

Further Reading
Comments
  1. Rajeev
    Rajeev

    Wonderful explanation … I really appreciate the author for explain in the simple words . Great work :)

  2. Efrat
    Efrat

    Thank you very much for the article. very helpful.
    !!!

  3. Mani
    Mani

    This article is great!

    I learned a lot and I believe that if every teacher in the world would teach that way, we would all have a Ph.D

    Thanks again,

    Mani

  4. Carlos
    Carlos

    Really easy to understand, thank you.

  5. Mani
    Mani

    this page is so informative for layman like me.

  6. someuser
    someuser

    Very useful article.

    If you get an exception like I was getting at:

    XmlSerializer mySerializer = new XmlSerializer(typeof(myTestClass));

    Make sure, the type and public properties in that type all have the parameterless constructor.

  7. Manikandan
    Manikandan

    Its very useful for very beginner of dot.net

  8. utpal das
    utpal das

    Can you please explain the exception "the writer is closed or in error state". I get this when i deserialize a saved file and populate my class, and again i try to serialize with the same name.

  9. Amey
    Amey

    Thanks a lot for this wonderful article.Keep it up.......

  10. Byron Nelson
    Byron Nelson

    Very nice little demo- exactly what I needed! I can't believe saving & retrieving structures is so easy. The times have sure changed.

  11. Aaron Cardoz
    Aaron Cardoz

    What about the [NonSerialized] decoration of a member.

    This can also be used to exclude it from being serialized.

    1. Tim Trott
      Tim Trott

      While [System.NonSerialized] can be used to exclude public fields from being serialised, it cannot be used on properties; [XmlIgnore] however can be used on either type.

      You would normally use NonSerialized to serialise to binary or SOAP, and XmlIgnore if you were serialising to XML with an XmlSerializer.

  12. geggio
    geggio

    Is it possible to exclude some field from being serialized? The example would be the case when I don't want the string myString in the output xml.
    thanks

    1. Tim Trott
      Tim Trott

      Yes it is possible to exclude a property from being serialised, simply add [XmlIgnore] before the declaration.

      Example:

      1. [Serializable]
      2. public class Product
      3. {
      4. public string StyleCode;
      5. public string Image;
      6. [XmlIgnore]
      7. public string Description;
      8. pubilc decimal Price;
      9. }
      10. }

      This will exclude Description from appearing in the serialised XML

  13. Sanjay Chatterjee
    Sanjay Chatterjee

    Article is too good to read. I am totally clear to serialization concept now. Before I was confused. Thanks for writing in such a straight forward way. Keep it up.

  14. Deven
    Deven

    Good One. Carry on the good work

  15. anant
    anant

    thanks its too good to read & understand

  16. Prasad
    Prasad

    Thank You for the Article

Leave a Reply

Your email address will not be published.