Introduction to XML Serialization

Many projects that I work on require me to serialize objects out to the file system and then retrieve them later. When I am serializing out program settings that are loaded in every time the program runs, I tend to use the Settings that come as a part of C# projects. If however the user can load or save settings, documents or projects, then I use the XmlSerializer class to save instances of a class out to XML. This allows me to automatically create a new document type based on my data classes and save them out with a few lines of code.

Because I do this so often, I have created a static helper class that has two methods that serialize/deserialize any type to/from an XML file. The two methods are:

public static void Serialize<T>( string filename, T data )
{
   TextWriter writer = null;
   try
   {
      writer = new StreamWriter( filename );
      XmlSerializer serializer = new XmlSerializer( typeof(T) );
      serializer.Serialize( writer, data );
   }
   finally
   {
      if ( writer != null )
      {
         writer.Close();
      }
   }
}

public static T Deserialize<T>( string filename )
{
   TextReader reader = null;
   T data = default(T);
   try
   {
      reader = new StreamReader( filename );
      XmlSerializer serializer = new XmlSerializer( typeof(T) );
      data = ( T )serializer.Deserialize( reader );
   }
   finally
   {
      if ( reader != null )
      {
         reader.Close();
      }
   }
   return data;
}

With these two methods, you can serialize a class out to XML or restore a class from XML with one line of code.

// Serialize out a person to XML
XmlSerializerHelper.Serialize<Person>( "person.xml", person );

// Deserialize the person from XML
Person person = XmlSerializerHelper.Deserialize<Person>( "person.xml" );

The XmlSerializer class will serialize out/in all public properties and members of the given class. One common error is that the class that you are serializing and all contained classes must have a public constructor that takes no parameters.

The class that you are serializing does not need to be modified, but if you want to control how the XML is serialized out, you can use several attributes.

By default, all properties are serialized out as XML elements. If you want to specify how the elements are serialized out, you can use the XmlElementAttribute and set properties on it such as ElementName.

Simple types such as string and int can be serialized out as Xml attributes if you prefer. To do this, mark the properties with the XmlAttributeAttribute.

If you want properties in your class to not be serialized, use the XmlIgnoreAttribute. This will usually be used for properties that are calculated based on the values of other properties.

For more, look at this Xml Serialization example project.

7 thoughts on “Introduction to XML Serialization

  1. Yes, it does handle null properties, but you must mark properties that may be null as such. Properties marked with XmlAttribute are nullable by default. Properties that are Xml elements must be marked like this;

    [XmlElement( IsNullable=true )]

    This assumes of course that the property is nullable (a reference, not a value type). I haven’t figured out yet how to work with .NET 2.0 nullable types like

    int? value;

  2. I came across this page looking for a solution to the problem i’m having and mentioned by Rob. Seems nullable types won’t serialize as attributes, only as elements. I use ALOT of nullable types in my apps (not sure its the best way to go, but oh well) and I was trying to add them ├ís attributes instead of elements (to eliminate part of the tag’s overhead) but I’ve had no luck.

    For now element’s is how it will be…

  3. Hi, I have a similar requirement to serialize a Business object into XML and I thought of using the XmlSerializer as well. But after a bit of experimentation i realized that there is no way to serialize properties that are read-only and the only workaround i could find was to have an empty set accessor for these props. Another particular type that i had problem with was TimeSpan. The XmlSerializer had no idea of how to serialize a TimeSpan type. So that means all my classes that have a Timespan prop have to inherit from IXmlSerializable and they must implement the WriteXml function of this interface. Did anyone else ever had a similar situation ? Please let me know.

    Thanks in anticipation.

  4. Pingback: C# Serializing Nullable Types by JohnnyCoder

  5. You could reduce the line count a little like this and retain the same logic:

    public static void Serialize(string filename, T data)
    {
    using ( TextWriter writer = new StreamWriter(filename) )
    {
    new XmlSerializer(typeof(T)).Serialize(writer, data);
    }
    }

    public static T Deserialize(string filename)
    {
    using ( TextReader reader = new StreamReader(filename) )
    {
    return (T)new XmlSerializer(typeof(T)).Deserialize(reader);
    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>