c# - DataContract 中字典的自定义序列化

标签 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 类进行 slove,但我不确定这是否会给 DataContractSerializer 带来一些麻烦。顺便说一句,该解决方案还应与 DataContractJsonSerializer 一起使用。

最佳答案

您遇到的问题是因为 IDictionary<'string, object> 是(在某种程度上)IEnumerable<'KeyValuePair<'string, object>>,这就是 DataContractSerializer 序列化每个 KeyValuePair 个性的方式。

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

使用 WriteXml 和 ReadXml 函数控制将 XmlWriter 作为参数传递到流中的 xml。

例如这个函数

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 & Value,123)。

哦,关于 JSON,有一个 IJsonSerializable但我从来没有抽出时间来使用它。

关于c# - DataContract 中字典的自定义序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11235041/

相关文章:

c# - 使用 vstest.consol.exe 运行 Moq 单元测试

c# - SetWindowPos 插入之后,而不是之前?

.net - 使用 DataContractSerializer 和 MetaDataTypeAttribute 问题自动生成 POCO 序列化

.net - 将枚举序列化为 int

f# - 多个数据成员属性

WCF - 在 DataContract 构造函数中实例化一个对象

c# - 无法远程连接数据库

c# - 如何将类型转换为它的通用基类型

c# - 我可以使用 XMLReader 创建表示文档中元素的对象吗?