【问题标题】:DataContract deserialization fails due to incorrect ordering of XML nodes由于 XML 节点的错误排序,DataContract 反序列化失败
【发布时间】:2012-03-20 22:46:51
【问题描述】:

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

有解决方法吗?可能是 DataContractSerializer 的某种设置?

【问题讨论】:

    标签: c# xml wcf datacontractserializer


    【解决方案1】:

    我最近遇到了这个问题。为了解决这个问题,我使用了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)必须由五个元素和一个属性组成。这些元素必须称为 name、street、city、state 和 zip,由声明的 name 属性的值指定,并且这些元素必须按照声明它们的相同顺序(顺序)出现。

    【讨论】:

    • 哇...这似乎有点太复杂了。但感谢您的回答。我最终尝试了 DataContractSerializer,它对我来说效果更好。
    • 有没有办法在 DataContract 中使用“xs:all”定义?那么顺序不重要了?
    • @Nicholi 如果您可以控制 WSDL
    【解决方案2】:

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

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

    【讨论】:

    • 我明白你的意思。我想我在这种情况下很懒,因为同一个对象被用作基于 WCF 的服务的参数,所以不考虑两种序列化方式是很方便的。
    猜你喜欢
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多