在DataContract中自定义字典序列化

时间:2012-06-27 21:25:56

标签: c# xml-serialization datacontract

基本上我有DataContract,其中包含Dictionary

[DataContract]
public class MyDictionary : IDictionary<string, object> {
    [DataMember(Name = "Data")]
    protected IDictionary<string, object> Dictionary { get; private set; }

    // ...
}

以下是XML输出的相关部分:

<Data>
 <a:KeyValueOfstringanyType>
  <a:Key>ID</a:Key>
  <a:Value i:type="s:int">2</a:Value>
 </a:KeyValueOfstringanyType>
 <a:KeyValueOfstringanyType>
  <a:Key>Value</a:Key>
  <a:Value i:type="s:int">4711</a:Value>
 </a:KeyValueOfstringanyType>
</Data>

如何在这里简化输出:

<Data>
  <ID i:type="s:int">2</ID>
  <Value i:type="s:int">4711</Value>
</Data>

字典键被限制为字符串,所以如果没有人得到使用非ascii键的愚蠢想法应该工作正常。我找到了属性CollectionDataContract,我更接近于我想要的东西,但是键值对将被保存完成,这会浪费内存。也许有可能与班级ISerializable一起解决,但我不确定这是否会对DataContractSerializer造成一些麻烦。顺便说一下,解决方案也应该与DataContractJsonSerializer一起使用。

1 个答案:

答案 0 :(得分:1)

您遇到的问题来自IDictionary&lt;'string,object&gt;是(在某种程度上)IEnumerable&lt;'KeyValuePair&lt;'string,object&gt;&gt;,这就是DataContractSerializer序列化每个KeyValuePair个性的方式。

您所询问的内容(如果我理解正确)是创建自定义序列化,为此您可以实现IXmlSerializable界面。

使用WriteXml和ReadXml函数控制写入流的xml,并将XmlWriter作为参数传递。

例如,这个函数

public void WriteXml(XmlWriter writer)
    {
        foreach (var pair in _dictionary)
        {
            writer.WriteElementString("Key", pair.Key);
            writer.WriteElementString("Value", pair.Value.ToString());
        }
    }

将产生此结果

<MyDictionary xmlns="http://schemas.datacontract.org/2004/07/Sandbox">
    <Key>ID</Key>
    <Value>15</Value>
    <Key>Value</Key>
    <Value>123</Value>
</MyDictionary>

假设已经在字典中输入了两对(ID,15&amp; Value,123)。

哦,关于JSON,有一个IJsonSerializable,但我从来没有开始使用它。