DataContractSerializer 和 Dictionary读取时失败
我正在使用 DataContractSerializer
序列化包含 Dictionary
成员的对象,该成员用 [DataMember()]
标记。这个想法是拥有一个灵活的对象属性包,但我不知道这些属性可能是什么。
当我将 int
、double
和 string
对象放入字典中时,这非常有用,但是当我放入 List
其中无法反序列化对象:
System.InvalidOperationException: Node type Element is not supported in this operation.
整个字典被序列化为 XML,并且看起来非常合理:
<Attributes xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>name</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">Test object</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>x</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">0.5</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>y</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">1.25</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>age</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:int">4</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>list-of-strings</d2p1:Key>
<d2p1:Value>
<d2p1:string>one string</d2p1:string>
<d2p1:string>two string</d2p1:string>
<d2p1:string>last string</d2p1:string>
</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
</Attributes>
请注意末尾的 list-of-strings
。它具有所有值,但没有任何内容表明它是 List
或任何内容。
处理这种情况的正确方法是什么?
I'm using DataContractSerializer
to serialize an object that contains a Dictionary<string,object>
member, which is marked with [DataMember()]
. The idea is to have a flexible bag of object attributes, and I don't know what those attributes could be.
This works great when I'm putting int
, double
and string
objects into the dictionary, but when I put a List<string>
in it fails to deserialize the object with:
System.InvalidOperationException: Node type Element is not supported in this operation.
The entire dictionary is serialized to XML, and it looks pretty reasonable:
<Attributes xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>name</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">Test object</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>x</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">0.5</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>y</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:double">1.25</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>age</d2p1:Key>
<d2p1:Value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:int">4</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
<d2p1:KeyValueOfstringanyType>
<d2p1:Key>list-of-strings</d2p1:Key>
<d2p1:Value>
<d2p1:string>one string</d2p1:string>
<d2p1:string>two string</d2p1:string>
<d2p1:string>last string</d2p1:string>
</d2p1:Value>
</d2p1:KeyValueOfstringanyType>
</Attributes>
Note the list-of-strings
at the end there. It's got all the values but nothing indicating that it's a List<string>
or anything.
What's the correct way of handling this situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试使用 KnownTypeAttribute 以便
DataContractSerializer
了解List
类型。不幸的是,这似乎违背了您不必事先了解类型的想法。我基于以下代码,该代码使用
DataContractSerializer
序列化包含List
的Dictionary
:您的
knownTypes
未提供给DataContractSerializer
,它会引发异常。Try using the KnownTypeAttribute so that
DataContractSerializer
knows about theList<string>
type. Unfortunately, that seems to go against your idea of not having to know about the types before hand.I'm basing this on the following code, which uses
DataContractSerializer
to serialize aDictionary<string, object>
containingList<string>
:If you
knownTypes
is not provided to theDataContractSerializer
, it throws an exception.WCF 无法知道您拥有的是一个
List
- 请注意,所有其他
元素都有一个“类型提示”( i:类型属性)。如果您想反序列化它,它需要有标记,并且您还需要告诉 WCFList
是“已知类型” - 见下文。有关已知类型(以及为什么需要它们)的更多信息,有许多< /a> 好资源在网络。WCF has no way of knowing that what you have is a
List<string>
there - notice that all the other<Value>
elements have a "type hint" (the i:type attribute). If you want to deserialize it, it needs to have the marking, and you also need to tell WCF thatList<string>
is a "known type" - see below. For more information on known types (and why they're needed) there are many good resources in the web.我多次有类似的想法,并且我使用附加字段来实现它,该字段保存所有字典项的程序集限定名称。它在每个项目添加或重写时填充列表,然后在序列化时使用它,并使用 XmlReader 提取类型信息、构建类型列表并反序列化对象。
代码:
I had a similiar idea number of times, and I implemented it with additional field holding assembly qualified names of all Dictionary items. It populates list on every item addition or rewrite, then uses it on serialization and uses XmlReader to extract type information, build list of types and deserialize object.
Code: