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

时间:2012-03-20 22:46:51

标签: c# xml wcf datacontractserializer

我对DataContractSerializer的行为感到困惑。我们的配置基于XML。 XML用作DataContractSerializer.ReadObject方法的源。最近,当没有设置反序列化对象的某些属性时,我遇到了一个问题。我已跟踪更改并发现这些属性已手动添加到XML中。在我看来哪个好。显然,在DataContractSerializer看来它不行,因为它似乎期望XML节点按字母顺序排序。真?!反序列化似乎非常简单 - 按顺序读取XML,解析节点名称,设置相应的属性。订购的目的是什么?

有解决方法吗?也许是DataContractSerializer的某种设置?

2 个答案:

答案 0 :(得分:3)

您可以使用DataMemberAttribute的Order成员来帮助解决这个问题,但在大多数情况下:XML是特定于订单的(对于元素而不是属性) - 所以它没有特别错误。

那就是说:如果你想要对XML序列化进行精细控制,那么DataContractSerializer是一个糟糕的选择XmlSerializer提供了更多的控制 - 并且不那么繁琐的重新命令iirc。

答案 1 :(得分:3)

我最近遇到了这个问题。要解决此问题,我使用了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"

...

有一些more information on my blog post

如果您想知道订单的重要性,那是因为XSD中的sequence具有已定义的订单,并且Web服务合同是使用XSD定义的。

来自the specification

  

此定义的结果是出现在其类型声明为USAddress的实例中的任何元素(例如po.xml中的shipTo)必须由五个元素和一个属性组成。这些元素必须被称为名称,街道,城市,州和邮政编码,由声明的名称属性的值指定,并且元素必须以声明它们的相同顺序(顺序)出现。