.Net Tips — Xml Serialize or Deserialize Dictionary in C#

If you try to serialize/deserialize a type which uses the gener­ic Dictionary<TKey, TVal­ue> type with the XmlSe­ri­al­iz­er then you’ll get an Invali­d­Op­er­a­tionEx­cep­tion, for instance:

Here’s my class:

public class MyClass
{
    // need a parameterless constructor for serialization
    public MyClass()
    {
        MyDictionary = new Dictionary<string, string>();
    }
    public Dictionary<string, string> MyDictionary { get; set; }
}

I’ll get an Invali­d­Op­er­a­tionEx­cep­tion with an inner excep­tion of type Not­Sup­port­edEx­cep­tion when I do this:

var xmlSerializer = new XmlSerializer(typeof(MyClass));

And the error mes­sage of the Not­Sup­port­edEx­cep­tion is:

Can­not seri­al­ize mem­ber MyClass.MyDictionary of type System.Collections.Generic.Dictionary‘2[[System.String, mscor­lib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscor­lib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], because it imple­ments IDic­tionary.”

The rea­son why Dictionary<TKey, TVal­ue> is not sup­port­ed by the XmlSe­ri­al­iz­er is that types such as Dic­tio­nary, HashTable, etc. needs an equal­i­ty com­par­er which can’t be seri­al­ized into XML eas­i­ly and won’t be portable any­how. To get around this prob­lem, you gen­er­al­ly have two options, in the order of my per­son­al pref­er­ence:

Use DataContractSerizalizer

The eas­i­est, and clean­est solu­tion is to switch over to data con­tract seri­al­iza­tion, and the only change required would be to mark your class with the Dat­a­Con­trac­tAt­tribute and mark the prop­er­ties you want to seri­al­ize with the DataMem­ber­At­tribute. My class would now look like this:

[DataContract]
public class MyClass
{
    // need a parameterless constructor for serialization
    public MyClass()
    {
        MyDictionary = new Dictionary<string, string>();
    }
    [DataMember]
    public Dictionary<string, string> MyDictionary { get; set; }
}

And to seri­al­ize it into Xml, just use the Dat­a­Con­tract­Se­ri­al­iz­er and write the out­put with a Xml­Tex­tWriter like this:

var serializer = new DataContractSerializer(typeof(MyClass));
string xmlString;
using (var sw = new StringWriter())
{
    using (var writer = new XmlTextWriter(sw))
    {
        writer.Formatting = Formatting.Indented; // indent the Xml so it's human readable
        serializer.WriteObject(writer, marketplace);
        writer.Flush();
        xmlString = sw.ToString();
    }
}

Use a custom Dictionary type

The alter­na­tive is to cre­ate your own Dic­tio­nary imple­men­ta­tion which is Xml seri­al­iz­able. See the ref­er­ences sec­tion for an imple­men­ta­tion Paul Wel­ter has cre­at­ed.

References:

XML Seri­al­iz­able Gener­ic Dic­tio­nary