If you try to serialize/deserialize a type which uses the generic Dictionary<TKey, TValue> type with the XmlSe­ri­al­izer 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 IDictionary.”

The rea­son why Dictionary<TKey, TValue> is not sup­ported by the XmlSe­ri­al­izer is that types such as Dic­tio­nary, HashTable, etc. needs an equal­ity com­parer which can’t be seri­al­ized into XML eas­ily and won’t be portable any­how. To get around this prob­lem, you gen­er­ally have two options, in the order of my per­sonal preference:

Use Dat­a­Con­tract­Ser­iza­l­izer

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­izer 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 cus­tom Dic­tio­nary 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 created.

Ref­er­ences:

XML Seri­al­iz­able Generic Dictionary

Share
  • soggez

    great stuff! exactly what i needed. thx for your work and posting.

  • http://aa Nanek

    serializer.WriteObject(writer, mar­ket­place);

    where does mar­ket­place come from?

  • the­burn­ing­monk

    @Nanek — imag­ine ‘mar­ket­place’ being an instance of ‘MyClass’, looks like I missed out a line or two of the code snippet

  • Methil

    Thank you for shar­ing this.

  • http://blog.intninety.co.uk/ int­ninety

    Thanks for the information.

    Just thought I’d add — you need to add a ref­er­ence to System.Runtime.Serialization for this, and it is only avail­able in .NET 3 upwards.

  • Pingback: [C#] Dictionary ?? Xml « Develope note

  • http://www.maltercorp.com Mike Mal­ter

    Thank you very much for this post. I really needed some­thing like this.

  • http://www.dotmaniac.net Torsten

    Thank you. This helped me seri­al­ize an object not seri­al­iz­able with stan­dard xml serializer.

  • Pier

    Great!
    I’d add that for Dat­a­Con­tract­Ser­iza­l­izer a ref­er­ence to System.Runtime.Serialization is nec­es­sary.
    Thnaks, guy!

  • radex

    Thanks. how do you then read/deserialize it?