Introduction
During the development process of our project, the need arose to serialize objects to XML. For this purpose, the .NET provides the XmlSerializer
class to serialize objects. This class has some disadvantages, however.
First, the creation of the class is expensive in performance. This is caused by the fact the class creates an in-memory assembly to quickly read and write from the objects to serialize. It does this by using reflection to inspect the object. This leads to the second disadvantage; only public properties and fields are serialized. These properties also have to be writable so that the XmlSerializer
can set the properties during deserialization. This leads to problems encapsulating your code. Finally, but not less important, it does not support the ISerializable
interface.
Alternatives
To get around these problems, you can use the SoapFormatter
class to serialize the object to SOAP. This class does support the ISerializable
interface, and does not use reflection. The resulting XML, however, is less accessible than the plain XML the XmlSerializer
produces, and has a lot of overhead. The only thing left is to create your own formatter by implementing the IFormatter
interface.
XmlFormatter
The code accompanied by this article contains our XmlFormatter
class that has the following features:
- Produces more clean XML than the SOAP structure of the
SoapFormatter
- Supports the
ISerializable
interface
- Does not impact performance by creating in-memory assemblies
The following example shows the use of the formatter, by serializing a class called MyObject
:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
namespace XmlFormatterSample
{
[Serializable]
public class MyObject : ISerializable
{
public string MyPublicProperty
{
get { return _myPublicProperty; }
set { _myPublicProperty = value; }
}
private string _myPublicProperty;
private string MyPrivateProperty
{
get { return _myPrivateProperty; }
set { _myPrivateProperty = value; }
}
private string _myPrivateProperty;
public MyObject()
{
this._myPublicProperty = "This is my public property";
this._myPrivateProperty = "This is my private property";
}
public string GetProperties()
{
string properties = "MyPublicProperty = " +
MyPublicProperty + "\r\n";
properties += "MyPrivateProperty = " +
MyPrivateProperty;
return properties;
}
#region ISerializable Members
public MyObject(SerializationInfo info,
StreamingContext context)
{
_myPublicProperty = info.GetString("MyPublicProperty");
_myPrivateProperty = info.GetString("MyPrivateProperty");
}
public void GetObjectData(SerializationInfo info,
StreamingContext context)
{
info.AddValue("MyPublicProperty", MyPublicProperty);
info.AddValue("MyPrivateProperty", MyPrivateProperty);
}
#endregion
}
}
The following code serializes and deserializes the object from and to a MemoryStream
using our XmlFormatter
. Please note that both the public and the private properties are being serialized.
using DotNetMagazine.September.Examples;
using System.IO;
using System.Xml;
using System.Data.SqlTypes;
namespace XmlFormatterSample
{
class Program
{
static void Main(string[] args)
{
MyObject object1 = new MyObject();
MyObject object2;
Console.WriteLine("The properties of object1 are:");
Console.WriteLine(object1.GetProperties());
Console.WriteLine();
MemoryStream stream = new MemoryStream();
XmlFormatter serializer =
new XmlFormatter(typeof(MyObject));
serializer.Serialize(stream, object1);
stream.Position = 0;
SqlXml xml = new SqlXml(stream);
Console.WriteLine("Xml value of object 1:");
Console.WriteLine(xml.Value);
Console.WriteLine();
using (MemoryStream stream2 =
new MemoryStream(Encoding.UTF8.GetBytes(xml.Value)))
{
object2 = (MyObject)serializer.Deserialize(stream2);
}
Console.WriteLine("The properties of object2 are:");
Console.WriteLine(object2.GetProperties());
Console.WriteLine();
Console.WriteLine("Press any key to continue");
Console.ReadKey();
}
}
}
The code is free to use in your projects. This code is also part of an article published in the Dutch version of the .NET magazine, September issue 2006: "Objecten en Sql Server 2005, XML als intermediair". We hope this formatter will be of use to you!