My XmlSerializer Pattern

Author:

The idea behind the .NET System.Xml.Serialization.XmlSerializer class is that you can easily serialize an XML file into a class tree and vice versa.

If you’re using XML Schema files, the xsd.exe tool can create that class tree for you.

But for simple applications you don’t even need a schema. You simply create a class that has public properties of simple types or complex types that in turn contain simple types.

Then you can throw this object into the XmlSerializer and you’re done. 🙂

Here’s my personal XmlSerializer coding pattern for a simple list of settings:

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

[Serializable()]
[XmlRoot()]
public class Settings
{
   private static XmlSerializer s_Serializer;

   [XmlArray("SettingsList")]
   [XmlArrayItem("Setting")]
   public Setting[] SettingsList;

   static Settings()
   {
      //This way is safer than the more obvious
      //s_Serializer = new XmlSerializer(typeof(Settings));
      XmlReflectionImporter importer 
         = new XmlReflectionImporter();
      XmlTypeMapping xmlMapping = importer
         .ImportTypeMapping(typeof(Settings), null, null);
      XmlSerializerFactory factory 
         = new XmlSerializerFactory();
      s_Serializer = factory.CreateSerializer(xmlMapping);
   }

   public static Settings Deserialize(String filename)
   {
      using (FileStream stream = new FileStream(filename
         , FileMode.Open, FileAccess.Read, FileShare.Read))
      {
         return (s_Serializer.Deserialize(stream) as Settings);
      }
   }

   public void Serialize(String filename)
   {
      using (FileStream stream = new FileStream(filename
         , FileMode.Create, FileAccess.Write, FileShare.Read))
      {
         using (XmlTextWriter writer = new XmlTextWriter(stream
            , Encoding.UTF8))
         {
            writer.Formatting = Formatting.Indented;
            s_Serializer.Serialize(writer, this);
         }
      }
   }
}

[Serializable()]
public class Setting
{
   public String Key;

   public String Value;
}

Or maybe you want a simple way to have a crash report when your application crashes for yet unknown reasons:

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

[Serializable()]
[XmlRoot()]
public class ExceptionXml
{
   private static XmlSerializer s_Serializer;

   public String Type;

   public String Message;

   public String StackTrace;

   public ExceptionXml InnerException;

   static ExceptionXml()
   {
      //This way is safer than the more obvious
      //s_Serializer 
      //   = new XmlSerializer(typeof(ExceptionXml));
      XmlReflectionImporter importer 
         = new XmlReflectionImporter();
      XmlTypeMapping xmlMapping = importer
         .ImportTypeMapping(typeof(ExceptionXml), null, null);
      XmlSerializerFactory factory 
         = new XmlSerializerFactory();
      s_Serializer = factory.CreateSerializer(xmlMapping);
   }

   public static ExceptionXml Deserialize(String filename)
   {
      using (FileStream stream = new FileStream(filename
         , FileMode.Open, FileAccess.Read, FileShare.Read))
      {
         return (s_Serializer.Deserialize(stream) 
            as ExceptionXml);
      }
   }

   public void Serialize(String filename)
   {
      using (FileStream stream = new FileStream(filename
         , FileMode.Create, FileAccess.Write, FileShare.Read))
      {
         using (XmlTextWriter writer = new XmlTextWriter(stream
            , Encoding.UTF8))
         {
            writer.Formatting = Formatting.Indented;
            s_Serializer.Serialize(writer, this);
         }
      }
   }

   public ExceptionXml()
   {
   }

   public ExceptionXml(Exception ex)
   {
      if (ex != null)
      {
         this.Type = ex.GetType().FullName;
         this.Message = ex.Message;
         this.StackTrace = ex.StackTrace;
         if (ex.InnerException != null)
         {
            this.InnerException 
               = new ExceptionXml(ex.InnerException);
         }
      }
   }
}