Creating a custom serialization class

Sometimes it is not enough to mark a whole class as serializable, quite often a class will have .net internal type that is not serializable, for example XmlDocument. In such case we need a wrapper class that is derived from ISerializable interface.

[Serializable]
class Student
{
	public string Name;
	public string Surname;
	public int Age;
	public XmlDocument Document;
}

The class from above would not serialize, because XmlDocument class is not serializable by default.

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Additional information: Type 'System.Xml.XmlDocument' in Assembly 'System.Xml, Version=4.0.0.0, Culture=neutral

To work around this problem create a new class that is derived from XmlDocument and ISerializable

[Serializable]
class StudentXmlDocument : XmlDocument, ISerializable
{
	public StudentXmlDocument() { }
	public StudentXmlDocument(SerializationInfo info, StreamingContext context)
	{
		base.LoadXml(info.GetString("xmlDoc"));
	}
	public void GetObjectData(SerializationInfo info, StreamingContext context)
	{
		info.AddValue("xmlDoc", base.OuterXml, typeof(String));
	}
}

GetObjectData method comes from ISerializable interface, this method will be called when an object is being serialized. Just add all required objects to the SerializationInfo.

Second part in this wrapper is a constructor that takes in two parameters. This constructor will be executed when an object is deserialized.

Afterwards replace XmlDocument property type with StudentXmlDocument

[Serializable]
class Student
{
	public string Name;
	public string Surname;
	public int Age;
	public StudentXmlDocument Document;
}
comments powered by Disqus