Como XML serializar um dictionary

Eu tenho sido capaz de serializar um IEnumerable desta maneira:

[XmlArray("TRANSACTIONS")] [XmlArrayItem("TRANSACTION", typeof(Record))] public IEnumerable Records { get { foreach(Record br in _budget) { yield return br; } } } 

No entanto, percebi que agora preciso de um dictionary que contenha uma coleção Dictionary (RecordCollection implementa IEnumerable).

Como posso conseguir isso?

Eu usei o abaixo por algum tempo. Originalmente vem daqui .

 namespace SerializeDictionary { using System; using System.Collections.Generic; using System.Runtime.Serialization; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; ///  /// Represents an XML serializable collection of keys and values. ///  /// The type of the keys in the dictionary. /// The type of the values in the dictionary. [Serializable] [XmlRoot("dictionary")] public class SerializableDictionary : Dictionary, IXmlSerializable { ///  /// The default XML tag name for an item. ///  private const string DefaultItemTag = "item"; ///  /// The default XML tag name for a key. ///  private const string DefaultKeyTag = "key"; ///  /// The default XML tag name for a value. ///  private const string DefaultValueTag = "value"; ///  /// The XML serializer for the key type. ///  private static readonly XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); ///  /// The XML serializer for the value type. ///  private static readonly XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); ///  /// Initializes a new instance of the ///  class. ///  public SerializableDictionary() { } ///  /// Initializes a new instance of the ///  class. ///  /// A ///  object /// containing the information required to serialize the /// . ///  /// A ///  structure /// containing the source and destination of the serialized stream /// associated with the /// . ///  protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { } ///  /// Gets the XML tag name for an item. ///  protected virtual string ItemTagName { get { return DefaultItemTag; } } ///  /// Gets the XML tag name for a key. ///  protected virtual string KeyTagName { get { return DefaultKeyTag; } } ///  /// Gets the XML tag name for a value. ///  protected virtual string ValueTagName { get { return DefaultValueTag; } } ///  /// Gets the XML schema for the XML serialization. ///  /// An XML schema for the serialized object. public XmlSchema GetSchema() { return null; } ///  /// Deserializes the object from XML. ///  /// The XML representation of the object. public void ReadXml(XmlReader reader) { var wasEmpty = reader.IsEmptyElement; reader.Read(); if (wasEmpty) { return; } try { while (reader.NodeType != XmlNodeType.EndElement) { this.ReadItem(reader); reader.MoveToContent(); } } finally { reader.ReadEndElement(); } } ///  /// Serializes this instance to XML. ///  /// The XML writer to serialize to. public void WriteXml(XmlWriter writer) { foreach (var keyValuePair in this) { this.WriteItem(writer, keyValuePair); } } ///  /// Deserializes the dictionary item. ///  /// The XML representation of the object. private void ReadItem(XmlReader reader) { reader.ReadStartElement(this.ItemTagName); try { this.Add(this.ReadKey(reader), this.ReadValue(reader)); } finally { reader.ReadEndElement(); } } ///  /// Deserializes the dictionary item's key. ///  /// The XML representation of the object. /// The dictionary item's key. private TKey ReadKey(XmlReader reader) { reader.ReadStartElement(this.KeyTagName); try { return (TKey)keySerializer.Deserialize(reader); } finally { reader.ReadEndElement(); } } ///  /// Deserializes the dictionary item's value. ///  /// The XML representation of the object. /// The dictionary item's value. private TValue ReadValue(XmlReader reader) { reader.ReadStartElement(this.ValueTagName); try { return (TValue)valueSerializer.Deserialize(reader); } finally { reader.ReadEndElement(); } } ///  /// Serializes the dictionary item. ///  /// The XML writer to serialize to. /// The key/value pair. private void WriteItem(XmlWriter writer, KeyValuePair keyValuePair) { writer.WriteStartElement(this.ItemTagName); try { this.WriteKey(writer, keyValuePair.Key); this.WriteValue(writer, keyValuePair.Value); } finally { writer.WriteEndElement(); } } ///  /// Serializes the dictionary item's key. ///  /// The XML writer to serialize to. /// The dictionary item's key. private void WriteKey(XmlWriter writer, TKey key) { writer.WriteStartElement(this.KeyTagName); try { keySerializer.Serialize(writer, key); } finally { writer.WriteEndElement(); } } ///  /// Serializes the dictionary item's value. ///  /// The XML writer to serialize to. /// The dictionary item's value. private void WriteValue(XmlWriter writer, TValue value) { writer.WriteStartElement(this.ValueTagName); try { valueSerializer.Serialize(writer, value); } finally { writer.WriteEndElement(); } } } } 

Por favor, tente esta alternativa mais fácil:

 void Main() { var source= new TestClass() { GroupTestTyped= new Dictionary { {"A", 23}, {"B", 40} } }; using (var writer = XmlWriter.Create("c:\\test1.xml")) (new XmlSerializer(typeof(TestClass))).Serialize(writer, source); } [Serializable] public class DemoElementClass { public string Key { get; set; } public int Value { get; set; } } [Serializable] public class TestClass { public TestClass() { } [XmlArray] [XmlArrayItem(ElementName = "ElementTest")] public List GroupTest { get; set; } [XmlIgnore] public Dictionary GroupTestTyped { get { return GroupTest.ToDictionary(x=> x.Key, x => x.Value); } set { GroupTest = value.Select(x => new DemoElementClass() {Key = x.Key, Value = x.Value}).ToList(); } } } 

Aqui o resultado xml:

     A 23   B 40    

Aqui está uma versão ainda mais curta baseada na resposta do Gildors:

 [XmlElement("Dictionary")] public List> XMLDictionaryProxy { get { return new List>(this.Dictionary); } set { this.Dictionary = new Dictionary(); foreach (var pair in value) this.Dictionary[pair.Key] = pair.Value; } } [XmlIgnore] public Dictionary Dictionary { get; set; } 

Apreciar.