gpt4 book ai didi

c# - 为什么 WCF DataContract 不按字母顺序序列化成员?

转载 作者:行者123 更新时间:2023-11-30 16:57:55 24 4
gpt4 key购买 nike

我有几个看起来与此类似的 DataContract(为简洁起见缩短):

[DataContract(Name = "ItemDTO", Namespace = "http://foo.com/")]
public class ItemDTO : IExtensibleDataObject
{
[DataMember(IsRequired = true)]
public string Name { get; set; }

[DataMember]
public string Value { get; set; }

[DataMember(IsRequired = true)]
public int Id { get; set; }

public ExtensionDataObject ExtensionData { get; set; }
}

我以前没有注意到序列化的消息,但在最近的一次更改之后,完成了两件事:我添加了一个名为 ReturnCode 的新属性,并运行了 CodeMaid的“重组”,按字母顺序排列属性。

现在看起来像这样:

[DataContract(Name = "ItemDTO", Namespace = "http://foo.com/")]
public class ItemDTO : IExtensibleDataObject
{
public ExtensionDataObject ExtensionData { get; set; }

[DataMember(IsRequired = true)]
public int Id { get; set; }

[DataMember(IsRequired = true)]
public string Name { get; set; }

[DataMember]
public int ReturnCode { get; set; }

[DataMember]
public string Value { get; set; }
}

根据 Microsoft's page on Data Contract Member Order我意识到 ReturnCode 会破坏契约,因为序列化程序会在 Value 之前插入它,所以我添加了一个 Order 属性值,假设原始顺序是字母顺序,产生:

[DataContract(Name = "ItemDTO", Namespace = "http://foo.com/")]
public class ItemDTO : IExtensibleDataObject
{
public ExtensionDataObject ExtensionData { get; set; }

[DataMember(IsRequired = true, Order = 0)]
public int Id { get; set; }

[DataMember(IsRequired = true, Order = 1)]
public string Name { get; set; }

[DataMember(Order = 3)]
public int ReturnCode { get; set; }

[DataMember(Order = 2)]
public string Value { get; set; }
}

然而,这引发了反序列化成员乱序的异常。我回滚到之前的变更集,在所有变更之前,果然成员的原始顺序在 SOAP 请求中不是按字母顺序排列的(通过 Fiddler 查看),而是遵循代码中表达的原始顺序,即:名称Id

我目前正在向我所有的旧 DTO 类型添加 Order 值,以便根据它们先前的、预先按字母顺序排列的属性和排列对它们进行排序。我想知道的是,为什么序列化程序使用的是编码顺序而不是字母顺序? Microsoft's rules说:

Next in order are the current type’s data members that do not have the Order property of the DataMemberAttribute attribute set, in alphabetical order.

更新:

在我添加 Order 值以按其原始顺序对属性进行排序后,我再次运行 Fiddler并且它仍然使用项目的字面编码顺序。换句话说,出于某种原因,我的 WCF 服务完全忽略任何序列化排序逻辑,只是按照它们在 .cs 文件中出现的顺序对属性进行排序。事实上,我能够让它正确序列化的唯一方法是将每种类型的属性物理地重新排列为它们的原始顺序。这行得通,但不是首选。

更新 2 - 解决方案:

按照 Dracor 的建议,我向我的 DTO 添加了 [XmlElement(Order = 1)] 属性和一个 XmlRootAttribute。 SOAP 序列化 DID 最终遵循这些属性分配的顺序。我没有考虑过,但我的服务确实使用了 Castle DynamicProxy所以我猜它正在将序列化程序从 DataContractSerializer 更改为 XmlSerializer

最佳答案

为什么不简单地使用 XmlSerializer 来序列化/反序列化您的 XML?它比 DataContractSerializer 更宽容,并且大部分时间都有效。

关于c# - 为什么 WCF DataContract 不按字母顺序序列化成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25939303/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com