简体   繁体   English

由于XML节点的排序不正确,DataContract反序列化失败

[英]DataContract deserialization fails due to incorrect ordering of XML nodes

I am baffled with the behavior of the DataContractSerializer. 我对DataContractSerializer的行为感到困惑。 Our configuration is XML based. 我们的配置基于XML。 XML is used as source for DataContractSerializer.ReadObject method. XML用作DataContractSerializer.ReadObject方法的源。 Recently I have encountered a problem when some properties of deserialized object were not set. 最近,当没有设置反序列化对象的某些属性时,我遇到了一个问题。 I have tracked the changes and discovered that those properties were added into XML manually. 我已跟踪更改并发现这些属性已手动添加到XML中。 Which is OK in my opinion. 在我看来哪个好。 Apparently it was not OK in DataContractSerializer's opinion because it appears it expects XML nodes to be ordered alphabetically. 显然,在DataContractSerializer看来它不行,因为它似乎期望XML节点按字母顺序排序。 Really?! 真?! Deserialization seems like really straightforward thing - read XML sequentially, parse node name, set corresponding property. 反序列化似乎非常简单 - 按顺序读取XML,解析节点名称,设置相应的属性。 What's the purpose of ordering? 订购的目的是什么?

Is there a workaround? 有解决方法吗? Maybe some sort of settings for DataContractSerializer? 也许是DataContractSerializer的某种设置?

You can use the Order member of DataMemberAttribute to help with this, but in most cases: XML is order-specific (for elements, not attributes) - so it isn't specifically wrong. 您可以使用DataMemberAttribute的Order成员来帮助解决这个问题,但在大多数情况下:XML是特定于订单的(对于元素而不是属性) - 所以它没有特别错误。

That said: if you want fine control over XML serialization, DataContractSerializer is a poor choice XmlSerializer offers more control - and is less fussy re order iirc. 这就是说:如果你想要对XML序列化进行精细控制,那么DataContractSerializer是一个糟糕的选择XmlSerializer提供了更多的控制 - 并且不那么繁琐的重新命令iirc。

I encountered this problem recently. 我最近遇到了这个问题。 To work around it, I used the XmlSerializer and removed the explicit ordering from the XmlElement attributes: 为了解决这个问题,我使用了XmlSerializer并从XmlElement属性中删除了显式排序:

set proxy_tool="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SvcUtil.exe" /nologo /t:code /ser:XmlSerializer /UseSerializerForFaults
set sed_tool="$(ProjectDir)sed.exe" -r -i "s/,?[[:space:]]*Order=[[:digit:]]+//"

%proxy_tool%  /o:"Proxy1.cs" /n:*,Namespaces.Name1 "Proxy1.wsdl"
%sed_tool% "Proxy1.cs"

%proxy_tool%  /o:"Proxy2.cs" /n:*,Namespaces.Name2 "Proxy2.wsdl"
%sed_tool% "Proxy2.cs"

...

There's some more information on my blog post . 我的博客文章中更多信息

If you want to know why the order matters, it's because a sequence in XSD has a defined order, and the web service contracts are defined with XSD. 如果您想知道订单的重要性,那是因为XSD中的sequence具有已定义的顺序,而Web服务合同是使用XSD定义的。

From the specification : 规格

The consequence of this definition is that any element appearing in an instance whose type is declared to be USAddress (eg shipTo in po.xml) must consist of five elements and one attribute. 此定义的结果是,出现在其类型声明为USAddress的实例中的任何元素(例如po.xml中的shipTo)必须由五个元素和一个属性组成。 These elements must be called name, street, city, state and zip as specified by the values of the declarations' name attributes, and the elements must appear in the same sequence (order) in which they are declared. 这些元素必须称为名称,街道,城市,州和邮政编码,由声明的名称属性的值指定, 并且元素必须以声明它们的相同顺序(顺序)出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM