天天看點

XML Serializable Generic Dictionary

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

For some reason( XML Serialization in the .NET Framework), the generic Dictionary in .net 2.0 is not XML serializable.  The following code snippet is a xml serializable generic dictionary.  The dictionary is serialzable by implementing the IXmlSerializable interface. 

    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);

                this.Add(key, value);

                reader.MoveToContent();

            }

            reader.ReadEndElement();

        public void WriteXml(System.Xml.XmlWriter writer)

            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);

        #endregion

    }

<b>Update:</b> Fixed bug Justin pointed out by adding an extra reader.ReadEndElement() and by checking the IsEmptyElement property.