0

I have this class in C#

public class ExerciseDTO {
    Dictionary<String, String> qa;
    private String materialId, content, topic;

    //constructors

    //properties

    public void makePersistent(String path) {
        Stream outputStream = File.OpenWrite(path + @"\" + this.topic + ".xml");
        XmlSerializer serializer = new XmlSerializer(typeof(ExerciseDTO));
        serializer.Serialize(outputStream, this);
        outputStream.Flush();
        outputStream.Close();
    }
}

Calling the makePersistent method makes the app throw an exeption with message An error occured while reflecting object of type ExerciseDTO. Why can't I serialize instances of this class?

3 Answers 3

4

Why can't I serialize instances of this class?

Because the XmlSerializer class doesn't support serializing Dictionary<TKey, TValue> properties.

As an alternative you could use the DataContractSerializer which supports dictionaries.

Sign up to request clarification or add additional context in comments.

3 Comments

The error says it had problems reflecting the object, I think the reflection implementation in the .NET platform should be independent of the XmlSerializer. Are you sure its only the XmlSerializer that can't persist Dictionary or all serializers?
No, only the XmlSerializer doesn't support Dictionaries. The DataContractSerializer works perfectly fine with dictionary types. I have updated my answer to include this information.
Thats brilliant then; you mean I can serialize a dictionary with the Binary serializer, right? Who care's about XML anyway? I just need to get my object persisted and retrieved.
0

What Darin said, the Dictionary is not XML serializable. You can create your own XmlSerializableDictionary. There are plenty good examples on the web. Here is one:

http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx

In case the link dies in the future, a copy/paste:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue>
    : Dictionary<TKey, TValue>, IXmlSerializable
{
    #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
        bool wasEmpty = reader.IsEmptyElement;

        reader.Read();

        if (wasEmpty)
            return;

        while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");
            reader.ReadStartElement("key");

            TKey key = (TKey)keySerializer.Deserialize(reader);

            reader.ReadEndElement();
            reader.ReadStartElement("value");

            TValue value = (TValue)valueSerializer.Deserialize(reader);
            reader.ReadEndElement();
            this.Add(key, value);
            reader.ReadEndElement();
            reader.MoveToContent();
        }

        reader.ReadEndElement();
    } 

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        foreach (TKey key in this.Keys)
        {
            writer.WriteStartElement("item");

            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();
            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();
            writer.WriteEndElement();
        }
    }
    #endregion
}

Comments

0
[Serializable]
public class ExerciseDTO {
...
}
  • You should also have a default (argument free) constructor
  • You should also make your property public, if you want to automatically serialize it
  • serialization of a Dictionary<> is not supported by .net, there are however workrounds, for instance this post.

Edit: as commented below: it should be "serialization of a Dictionary<> is not supported by the XmlSerializer class".

3 Comments

serialization of a Dictionary<> is not supported by .net Are you kidding me??? I even found out that it can't serialize references specified as interface types! WTH??? Now I think its accurate to say that .NET is the worst platform I've ever programmed on! I'll never use it for anything asides WindowsPhone again! Java excels by far!
serialization of a Dictionary<> is not supported by .net is not a true statement. A more correct statement is serialization of a Dictionary<> is not supported by the XmlSerializer class. You could use the DataContractSerializer class which supports dictionaries.
@DarinDimitrov, we always talk sth in context, I had already offered a link to get this done in .net, so you comment seems to be..., I don't know, I just wish that one can find sth useful from my answer, and I also hope that people can find sth useful from your comments as well. Anyway, I give an upvote for your updated comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.