Comparing .NET XML Serializers: Part One

Introduction

I was working on a large .NET application (.NET 3.5 SP1), and we began to argue what XML serializer is better for saving application state: user preferences, open windows, queries, and the like. The power of serializers and quality of resulting XML is best investigated on actual samples. I have built a small engine that runs each serializer on a set of samples, captures resulting XML or exception, and saves them in an XML output file. The results of this work are below.

Upcoming Parts

This parts contains mostly pure facts and very little analysis. I started to write a long text with insights and recommendations, which grew longer and longer, until I realized I am having a bad case of scope creep. Thus, I decided to apply the agile approach and release the first part without further delay.

XML Serializers Used

Starting with .NET 3.0 there are at least two other serializers available for general use besides XmlSerializer:

Class Name.NET versionComponent
XmlSerializer 1.0 General
XamlWriter / XamlReader 3.0 WPF
DataContractSerializer 3.0* WCF

* in .NET 3.5 SP1 Microsoft made a significant change in the behavior of DataContractSerializer.

Qualities Researched

We were interested primarily in these things:

Serialization Samples

WCF serializer is run in two modes: the "ref" mode that allows for cycles in the object graph, and the regular mode that does not permit cycles. The following table summarizes the results for .NET 3.5 SP1. This is important, because XAML serializer has much better generics support in .NET 4.0.

XmlSerializerXAML SerializerWCF SerializerWCF Serializer (ref)
TestWriteReadWriteReadWriteReadWriteRead
Empty ClassOKOKOKOKOKOKOKOK
One property of built-in typeOKOKOKOKOKOKOKOK
Property of type ColorOKOKOKOKOKOKOKOK
Null propertyOKOKOKOKOKOKOKOK
Generic listOKOKFailedSkippedOKOKOKOK
Generic list with Content attributeOKOKFailedSkippedOKOKOKOK
GenericListXamlContentPrivateSetterFailedSkippedOKFailedOKOKOKOK
Generic dictionaryFailedSkippedOKFailedOKOKOKOK
Generic dictionary that is never nullFailedSkippedOKFailedOKOKOKOK
Generic dictionary with custom key typeFailedSkippedFailedSkippedOKOKOKOK
Generic dictionary with custom value typeFailedSkippedOKFailedOKOKOKOK
Object graphOKOKFailedSkippedOKOKOKOK
Object graph with cycleSkippedSkippedSkippedSkippedFailedSkippedOKOK
XmlSerializableOKOKOKOKOKOKOKOK
Ignore a PropertyOKOKOKOKFailedSkippedFailedSkipped
MissingPropertyOKOKOKFailedOKOKOKOK

Brief Analysis of the Serialization Samples

XML Serializer

Good:

Bad:

XAML Serializer

Good:

Bad:

DataContractSerializer

Good:

Bad:

Serialization Engine

Serialization engine that produced the above table (with some XSLT) turned to be quite interesting program. You can download the source here; XmlSerializersTest.zip (45K). The application produces a large XML file with sample source and serialization results from all serializers. This file can be then transformed into a table via XSLT.

Conclusion

Based on this brief analysis, I think it is clear that XAML serializer is not suitable for serializing application state, mostly due to versioning issues and limitations on generics (prior to .NET 4.0).

Whether you use XmlSerializer or DataContractSerializer depends on a number of factors and personal preferenes, we will look at those in further detail in next parts.