After a little discussion at work on which XML serializer for .NET to use, I decided to do a little research. The candidates were the regular
XmlSerializer, the XAML serializer (
XamlReader) and the
DataContractSerializer from WCF.
Frankly, all of them suck in different ways, but the
DataContractSerializer shows the best results so far (for our purposes). I was looking for two things in a serializer:
- No or little restrictions on what can be serialized
- No unnecessary noise in the resulting XML
- Support for versioning
The second requirement is somewhat subjective, but we want our XML to be as human-readable as possible. Class names with some attributes work well. Long
namespace URLs on every corner don’t...
All serializers use CLR attributes to alter their behavior, which puts you out of luck if you want to customize serialization of a class that you cannot modify. Also, there can be only one way to serialize a class, if you need to serialize it differently under different circumstances, this is difficult.
XmlSerializer does not do dictionaries. Anything implementing
IDictionary is specifically excluded “This was partly due to schedule constraints and partly due to the fact that a hashtable does not have a counterpart in the XSD type system“. Apparently, dictionaries are not used widely in Microsoft, since they did not find time to revisit it in 7 or so years. It will, however, happily serialize generic lists. There are also versions of serializable dictionaries out there, and you can always write your own serialization of difficult parts by implementing
XAML Serializer produces relatively concise XML by putting primitive properties in attributes. It also handles WPF attributes like colors very well. Unfortunately, XAML serializer is very picky about generics in general, and lists and dictionaries in particular. They might occasionally work, but it is very quirky. Unlike other serializers, you cannot get around it by implementing your own custom serialization strategy – AFAIK, there is no equivalent of
IXmlSerializable for XAML. Also, by default, XAML serializer will include all
null attributes, so if your class has a lot of
nulls, your XML will be large.
WCF Serializer can serialize dictionaries and lists. It is the only serializer that can (in special mode) preserve references (the same object referenced twice) and process circular dependencies.
Shape of XML
By default, XML serializer produces verbose output: every single thing is an element. It can be made very nice, but it may require applying lots of attributes to your classes.
XAML serializer does not allow much control over the output. It has quite a few
namespace declarations, and may also get littered with
WCF serializer does not give you much control either, and everything is as an element. If you work in “preserve object references” mode, everything has an “
id” attribute on it.
XML serializer does not tie your code to class names, so with some tweaking, you can achieve a considerable amount of backward compatibility. It is also possible to serialize the output with one class and deserialize with another.
XAML serializer is the worst – it tightly couples the output to classes, assembly names, and down to property names, which makes versioning difficult. It will also fail if a particular property is not available upon deserialization. The only viable option I can think of is to add XSLT before deserializing.
WCF serializer allegedly has some built-in versioning considerations, but I need to research what they are.