Steve Wellens

Programming in the .Net environment

Sponsors

Links

Serializing and Deserializing Objects…to and from…XML

Over on the Asp.Net forums I recently had the opportunity* to help a few lost souls by showing them how to serialize objects to XML and deserialize the XML back into objects. Since the question has come up more than once, I decided to BLOG it so I could refer similar questions in the future to this post.

*I use the word opportunity because by helping others I am forced to think hard about the technology and to think even harder about how to communicate the technology. It makes me better at what I do. All right then, enough after-school-special-feel-good-about-yourself-I'm-ok-you're-ok fluffy nonsense… on with the code:

Here is a simple class I'm going to work with. It has both properties and fields:

public class MyClass
{
    // old school property
    private int _Age;  
    public int Age  
    {
        get { return _Age; }
        set { _Age = value; }
    }
 
    // new school property
    public bool Citizen { get; set; }
 
    // there's nothing wrong with using fields
    public string Name;  
}

Here are the two functions to Serialize and Deserialize an object:

/// ---- SerializeAnObject -----------------------------
/// <summary>
/// Serializes an object to an XML string
/// </summary>
/// <param name="AnObject">The Object to serialize</param>
/// <returns>XML string</returns>
 
public static string SerializeAnObject(object AnObject)
{
    XmlSerializer Xml_Serializer = new XmlSerializer(AnObject.GetType());
    StringWriter Writer = new StringWriter();      
 
    Xml_Serializer.Serialize(Writer, AnObject);
    return Writer.ToString();
}
 
 
/// ---- DeSerializeAnObject ------------------------------
/// <summary>
/// DeSerialize an object
/// </summary>
/// <param name="XmlOfAnObject">The XML string</param>
/// <param name="ObjectType">The type of object</param>
/// <returns>A deserialized object...must be cast to correct type</returns>
 
public static Object DeSerializeAnObject(string XmlOfAnObject, Type ObjectType)
{       
    StringReader StrReader = new StringReader(XmlOfAnObject);
    XmlSerializer Xml_Serializer = new XmlSerializer(ObjectType);
    XmlTextReader XmlReader = new XmlTextReader(StrReader);
    try
    {
        Object AnObject = Xml_Serializer.Deserialize(XmlReader);
        return AnObject;
    }
    finally
    {
        XmlReader.Close();
        StrReader.Close();
    }
}

Here is some sample code showing how to use the functions.

Note: I keep these functions (and other functions) in a class I call MiscUtilities. You will have to modify the code…depending on where you place the functions.

protected void Button1_Click(object sender, EventArgs e)
{
    // create and initialize an object
    MyClass Test = new MyClass();
 
    Test.Age = 18;
    Test.Name = "Rocky Balboa";
    Test.Citizen = true;
 
    //  Serialize it
    String XML;
 
    XML = MiscUtilities.SerializeAnObject(Test);
 
    // Deserialize it
    MyClass Test2;
 
    Test2 = MiscUtilities.DeSerializeAnObject(XML, typeof(MyClass)) as MyClass;
 
    // TODO:  Get a cup of coffee and bask in the glory of rock solid code.
}

Here is what the XML string looks like (after formatting):

<?xml version="1.0"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Rocky Balboa</Name>
  <Age>18</Age>
  <Citizen>true</Citizen>
</MyClass>

There are limitations: XmlSerializer does not serialize private fields, methods, indexers or read-only fields.

Once you have the XML string, you can email it, store it in a database, save it to disk, or…print a copy of it and have your mom tape it to the refrigerator next to the picture of a turkey you made in second grade by tracing around your hand with a Crayola crayon.

I hope someone finds this useful.

Comments

Scott Allen said:

I think a generic parameter on deserialize would be nice, because the caller would not have to cast the return value, and you'd have a cleaner method signature. The type coercion would be hidden inside deserialize.

public static T DeSerialize<T>(string XmlOfAnObject)

{

   ...

   return (T)anObject;

   ...

}

Gives you:

var foo = Deserialize<Bar>(xml);

# July 2, 2009 12:57 PM

Dave said:

What if a field is added to the class after the xml file is created. Will it throw an error if its missing in the xml when you try to reconstitute it?

If it does throw the error will it say what field is missing?

# July 2, 2009 2:34 PM

SGWellens said:

If a field is added to the class, the reconstitution of an object from an old XML string will ignore the new field.  However, you can create a default constructor that initializes new fields to their desired defaults.  

This is much better than doing a binary serialization where you would need to write a conversion program each time a new version was issued.  

# July 2, 2009 4:07 PM

Jv said:

Why not use this instead: support.microsoft.com/.../815813 ? It's native .NET

# July 3, 2009 4:13 AM

flalar said:

You could also use generics for serialization

public static string Serialize<T>(T objectToSerialize, XmlSerializer serializer) where T : new()

       {

           StringBuilder stringBuilder = new StringBuilder();

           using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder))

           {

               serializer.Serialize(xmlWriter, objectToSerialize);

               xmlWriter.Flush();

           }

           return stringBuilder.ToString();

       }

# July 3, 2009 5:46 AM

DotNetShoutout said:

Thank you for submitting this cool story - Trackback from DotNetShoutout

# July 6, 2009 6:21 AM

Zeeshan Umar said:

I generally use extension methods to Serilize and De-Serlize objetcs to XML. Thanks for sharing

# September 9, 2009 2:43 AM

Steve Wellens said:

In an earlier post here , I wrote two functions to Serialize and Deserialize objects to XML strings.

# January 6, 2010 1:33 PM

Serializing ArrayLists of Disparate Objects to XML Strings | I love .NET! said:

Pingback from  Serializing ArrayLists of Disparate Objects to XML Strings | I love .NET!

# January 6, 2010 4:19 PM

khushboo said:

I used the above code to serialize,but i have one problem,while deserializing the updated values for the object's members are lost and reset to the default values.I have put my code below...

public string SerializeObject(Object objToSerialize)

       {

           XmlSerializer ser = new XmlSerializer(objToSerialize.GetType());

                       StringWriter writer = new StringWriter();

           ser.Serialize(writer, objToSerialize);

                       writer.Close();

           return writer.ToString();

       }

Calling the above method like this...

string strXmlTaskList = ser.SerializeObject(objTaskListDO);

Deserialization code....

public object DeSerializeAnObject(string xmlOfAnObject, Type ObjectType)

       {

           StringReader strReader = new StringReader(xmlOfAnObject);

           XmlSerializer ser = new XmlSerializer(ObjectType);

           XmlTextReader XmlReader = new XmlTextReader(strReader);

           try

           {

               return ser.Deserialize(XmlReader);

           }

           catch (Exception ex)

           {

               throw new Exception(ex.StackTrace);

           }

           finally

           {

               XmlReader.Close();

               strReader.Close();

           }

       }

and calling this method like this...

TaskListDO deSerializedTaskListDO = (TaskListDO)objser.DeSerializeAnObject(strXmlObject, typeof(TaskListDO));

Please help me.

# June 10, 2010 2:50 AM

SGWellens said:

"I used the above code to serialize,but i have one problem,while deserializing the updated values for the object's members are lost and reset to the default values."

When you serialize an object, you get a text representation of the object at that time.  If you modify the object, the xml text isn't modified to reflect the changes.

# June 10, 2010 9:38 AM

Ken said:

I've got a model that has additional items declared as list(of T).  For example, product attributes and then list(of productimages) to go along with it.  

So I get a list(of model) and inside there is a nested list(of productimages).  Hope that's clear.

When I go to use SerializeAnObject, I get an error that says..."There was an error reflecting type 'System.Collections.Generic.List`1[itfindsit.Extensibility.Uniques.DisplayProduct]'."

Below is my model with the nested list.  Why isn't this working?  What do I need to change to get the SerializeAnObject to work?

   Public Class DisplayProduct

       Public Property Id() As String

           Get

               Return m_Id

           End Get

           Set(ByVal value As String)

               m_Id = value

           End Set

       End Property

       Private m_Id As String

       Public Property ProductName() As String

           Get

               Return m_ProductName

           End Get

           Set(ByVal value As String)

               m_ProductName = value

           End Set

       End Property

       Private m_ProductName As String

       Private m_ProductImages As List(Of ProductImage)

       Public Property ProductImages() As List(Of ProductImage)

           Get

               Return m_ProductImages

           End Get

           Set(ByVal value As List(Of ProductImage))

               m_ProductImages = value

           End Set

       End Property

   End Class

# March 17, 2011 5:29 PM

SGWellens said:

If you have questions you should post them on one of these sites/forums:

http://www.codeproject.com/

stackoverflow.com/unanswered

http://forums.asp.net/

However, I was curious and tried your class (after converting it to C#).  You didn't provide the class for ProductImage so I dummied up a simple one and everything worked.

So, I think you can focus on why ProductImage doesn't want to be serialized.  Good Luck!

# March 17, 2011 5:57 PM

Arun said:

nice one

# March 18, 2011 6:25 AM

Cognizant said:

Very very useful site. Nice article.

# September 30, 2011 5:43 AM

ff said:

Your page helped me a lot. Thanks for all the information and code samples.

# December 18, 2011 8:22 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)