n .NET 2.0, Microsoft has exposed the methods of the IXmlSerializable interface, giving you far more control over the way your objects get serialized to XML than in previous versions. Implementing IXmlSerializable in your own classes gives you explicit control over the XML schema as well as fine-grained control of the XML when serializing or deserializing your objects at runtime.
One of the most obvious weaknesses with XML serialization in .NET Framework 1.x was that it lacked the ability to customize the serialization and deserialization process. In that version, the IXmlSerializable interface provided limited serialization support geared primarily toward serializing DataSet objects. But in the .NET Framework 2.0, Microsoft has made the IXmlSerializable interface methods available for public consumptionmeaning that you can implement those methods to exercise a finer level of control over the XML serialization and deserialization process. This article explores the new serialization features and demonstrates how to leverage them in your applications.
In .NET Framework 1.x you could add attributes to types at design time and also override those attributes with new values at run time; however, the entire process was based on attributesyou never really had complete control over the serialization process. The IXmlSerializable interface methods that have been present in the .NET Framework since version 1.x. (but only for internal use), are now available for general use. They are:
Of the three methods above, the GetSchema()
method is now obsolete and you should not use it for serialization purposes. Accordingly, the GetSchema()
method should just throw a System.NotImplementedException. Instead, you need to implement a static method that generates the schema. You then pass this static method as an argument to the XmlSchemaProviderAttribute class constructor.
method converts an object into its XML representation. You have to write sufficient information to the XmlWriter stream to allow the ReadXml()
method to reconstitute your object. Note that a number of classes in the .NET Framework 2.0 class library implement the IXmlSerializable interface by default, so you can serialize and deserialize them easily.
How the IXmlSerializable Methods Work
To define your very own custom serialization and deserialization process you just need to follow a few steps.
- Implement the static method that generates the schema for the type
- Decorate the type with the new attribute named XmlSchemaProvider and specify the static method that generates and inserts the schema in the XmlSchemaSet.
- Implement the ReadXml() and WriteXml() methods. The ReadXml() method controls reading the serialized format. You provide it with an XmlReader to read from the stream and populate the type. The WriteXml() method controls writing the object in serialized form. You pass it an XmlWriter to write the data to the stream.
method generates an object from its XML representation. It must reconstitute your object using the information that was written before by the WriteXml()
method. When you first call this method, the reader stream is positioned at exactly the point that the WriteXml()
method began writing. Typically, this is immediately after the start tag that indicates the beginning of your serialized object. When this method returns, it must have consumed exactly those nodes that were written by the WriteXml method, so that reader stream is positioned where that method left it. That's it. There is actually one more official method called GetSchema()
that you must implement in the IXmlSerializable interface, but it's there for legacy purposes only.
Implementing the IXmlSerializable Interface
Now that you've had the basic overview of the various IXmlSerializable interface methods, here's an example implementation. Listing 1
shows an Employee class that implements IXmlSerializable.
The Employee class definition is marked with the XmlSchemaProvider attribute.
<XmlSchemaProvider ("CreateEmployeeSchema")> _
The XmlSchemaProviderAttribute class indicates the name of the method to call to get the schema added to the internal schema set. It takes an XmlSchemaSet and returns the XmlQualifiedName of the starting element.