Custom serialisation of a Dictionary in a DataContract

∥☆過路亽.° 提交于 2019-12-12 14:24:45

问题


Basically I have a DataContract which contains a Dictionary:

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

    // ...
}

Here is the relevent part of the XML output:

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

How can I simplify the output to something like this here:

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

The Dictionary key is restricted to string so if nobody get the stupid idea of using non ascii keys that should work fine. I found the attribute CollectionDataContract with that I come a little bit closer to what I want but the key value pairs will be saved compleate which wasts memory. Maybe it is possible to slove with the class ISerializable but I'm not sure if that makes some trouble with the DataContractSerializer. By the way the solution should also work with the DataContractJsonSerializer.


回答1:


The problem you are having comes from the fact that IDictionary<'string, object> is (in a way) IEnumerable<'KeyValuePair<'string, object>>, and that is way the DataContractSerializer serialize each KeyValuePair individuality.

What you are asking (if I understand correctly) is to create a custom serialization, and for that you can implement the IXmlSerializable interface.

Use the WriteXml, and ReadXml functions to control the xml written to the stream with the XmlWriter passed as parameter.

for example, this function

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

will yield this result

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

assuming two pairs has been entered to the dictionary (ID,15 & Value, 123).

Oh and about the JSON, there is an IJsonSerializable but I never got around to working with it.



来源:https://stackoverflow.com/questions/11235041/custom-serialisation-of-a-dictionary-in-a-datacontract

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!