Using .Net what limitations (if any) are there in using the XmlSerializer?

I generally find the XmlSerializer to be a poor choice for any POCO that’s more than just a DTO. If you require specific XML, you can go the Xml*Attribute and/or IXmlSerializable route – but you’re left with an object pretty mangled.

For some purposes, it still an obvious choice – even with it’s limitations. But, for simply storing and reloading data, I’ve found BinaryFormatter to be a much easier choice with less pitfalls.

Here’s a list of some annoyances with XmlSerializer – most I’ve been bitten by at one point or another, others I found over at MSDN:

  • Requires a public, no args constructor
  • Only serializes public read/write properties and fields
  • Requires all types to be known
  • Actually calls into get_* and set_*, so validation, etc. will be run. This may be good or bad (think about the order of the calls as well)
  • Will only serialize IEnumerable or ICollection collections conforming to specific rules

The XmlSerializer gives special treatment to classes that implement IEnumerable or ICollection. A class that implements IEnumerable must implement a public Add method that takes a single parameter. The Add method’s parameter must be of the same type as is returned from the Current property on the value returned from GetEnumerator, or one of that type’s bases.

A class that implements ICollection (such as CollectionBase) in addition to IEnumerable must have a public Item indexed property (indexer in C#) that takes an integer, and it must have a public Count property of type integer. The parameter to the Add method must be the same type as is returned from the Item property, or one of that type’s bases. For classes that implement ICollection, values to be serialized are retrieved from the indexed Item property, not by calling GetEnumerator.

  • Does not serialize IDictionary
  • Uses dynamically generated assemblies, which may not get unloaded from the app domain.

To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types. The infrastructure finds and reuses those assemblies. This behavior occurs only when using the following constructors:

XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)

If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance.

  • Cannot serialize ArrayList[] or List<T>[]
  • Has other weird edge cases

The XmlSerializer cannot be instantiated to serialize an enumeration if the following conditions are true: The enumeration is of type unsigned long (ulong in C#) and the enumeration contains any member with a value larger than 9,223,372,036,854,775,807.

The XmlSerializer class no longer serializes objects that are marked as [Obsolete].

You must have permission to write to the temporary directory (as defined by the TEMP environment variable) to deserialize an object.

  • Requires reading .InnerException to get any useful info on errors

Leave a Comment