30 .net wcf serialization
在非.NET客户端和.NET WCF服务之间传递序列化对象时,我遇到了一个反复出现的问题.
当WCF反序列化对象时,它严格依赖于属性的顺序.
也就是说,如果我将我的类定义为:
public class Foo
{
public int ID { get; set; }
public int Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后WCF将序列化对象,如下所示:
<Foo>
<Bar>123</Bar>
<ID>456</ID>
</Foo>
Run Code Online (Sandbox Code Playgroud)
注意:属性按字母顺序序列化.
如果您尝试反序列化具有Bar和ID交换位置的对象,WCF会将错误定位的元素视为null.
虽然我知道我可以使用该DataMember属性,并强制执行特定的排序,但我希望减少调试字段"神秘"为空的问题的次数.
所以,我的问题是:在反序列化对象时,是否可以告诉WCF反序列化器忽略字段的顺序.
mar*_*c_s 12
您可以通过修改数据协定中的元素来指定序列化顺序:
[DataContract]
public class Foo
{
[DataMember(Order=1)]
public int ID { get; set; }
[DataMember(Order=2)]
public int Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
因此,您可以确保序列化顺序始终相同.但是没有办法告诉解串器"忘记"顺序 - 重点是:这是通过XML模式处理的,并且使用<xs:sequence>元素完成- 这确实意味着需要顺序.我担心,你不能把它关掉.
基于该XML模式,您的非.NET客户端应该能够验证他们将要发送的XML是否符合该模式 - 如果不是因为Bar和ID元素已被交换,他们不应该发送无效的XML.
Joe*_*Joe 10
您可以使用DataMember属性的IsRequired属性指定元素是必需的.这样,您将获得更明确的错误消息,表明缺少必需的元素,而不是获得"神秘"的空值.
[DataContract]
public class Foo
{
[DataMember(IsRequired=true, Order=1)]
public int ID { get; set; }
[DataMember(IsRequired=true, Order=2)]
public int Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
您的案例中发生的事情是:
DataContract按此顺序需要Bar和ID元素(字母表,因为您没有指定显式顺序).
它遇到没有前面的Bar元素的ID元素.由于Bar不是必需的,它只是忽略它.
Bar后面的ID元素被忽略,因为它位于错误的位置.
话虽如此,将IsRequired设置为true只会对合同的第1版有所帮助.后续版本中添加的元素通常将IsRequired设置为false.MSDN有一篇关于数据合同版本控制的文章.
这里有一个旧线程:
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/a891928b-d27a-4ef2-83b3-ee407c6b9187
看起来唯一的选择是交换串行器,但随后它变得选择,这更令人讨厌.
编辑:您可以编写自己的序列化程序来重新排序元素,然后将其传递给DataContractSerializer.