【问题标题】:WCF Datacontract, some fields do not deserializeWCF Datacontract,某些字段不反序列化
【发布时间】:2010-03-25 20:46:34
【问题描述】:

问题:

我有一个 WCF 服务设置作为来自外部系统的调用的端点。呼叫正在发送纯 xml。我正在通过使用 RequestBuilder 从 Fiddler 向服务发送调用来测试系统。

问题是我的所有字段都被反序列化,但两个字段除外。 price_retail 和 price_wholesale。

我错过了什么?所有其他字段都反序列化没有问题 - 服务响应。就是这些领域。

XML 消息:

<widget_conclusion>
    <list_criteria_id>123</list_criteria_id>
    <list_type>consumer</list_type>
    <qty>500</qty>
    <price_retail>50.00</price_retail>
    <price_wholesale>40.00</price_wholesale>
    <session_id>123456789</session_id>
</widget_conclusion>

服务方式:

public string WidgetConclusion(ConclusionMessage message)
{
    var priceRetail = message.PriceRetail;
}

消息类:

[DataContract(Name = "widget_conclusion", Namespace = "")]
public class ConclusionMessage  
{
    [DataMember(Name = "list_criteria_id")]
    public int CriteriaId  { get; set;}
    [DataMember(Name = "list_type")]
    public string ListType { get; set; }
    [DataMember(Name = "qty")]
    public int ListQuantity { get; set; }
    [DataMember(Name = "price_retail")]
    public decimal PriceRetail { get; set; }
    [DataMember(Name = "price_wholesale")]
    public decimal PriceWholesale { get; set; }
    [DataMember(Name = "session_id")]
    public string SessionId { get; set; }
}

【问题讨论】:

    标签: wcf datacontractserializer


    【解决方案1】:

    您的消息的字段顺序错误。 DataContracts 默认按字母顺序和 not 声明顺序;并期望 XML 元素按该顺序到达;乱序元素通常会被丢弃。

    要么修复您的合同​​以明确指定正确的顺序(使用 DataMemberAttribute 的 Order 属性),要么确保您的客户以正确的顺序发送它们。

    【讨论】:

    • 好答案。我尝试了两种方法,行为正是你所描述的。错过简单的事情总是一种谦卑的经历。我对为什么 DataContracts 默认按字母顺序感兴趣。维护声明顺序似乎更具声明性......但我认为提供 Order 属性是最具声明性的。
    • 是的。我已经养成了始终明确声明顺序的习惯,这让以后的事情变得容易得多。
    • 是否有另一个序列化程序(除了早期的 XmlSerializer 之外)没有这种愚蠢的行为?因为如果我想要那种严格的超严格反序列化,我只会使用二进制。
    • 可选字段的使用怎么样? wsdl 中的 (minOccurs="0")?这可以是响应的一部分,也可以不是。所以它可以完全打乱顺序。
    • 我处于类似的情况,似乎一切都做对了,即:设置 [DataMember(Order=...)],但反序列化仍然不起作用。事实证明 [DataContract] 是必需的,以免为空,DCS 会考虑 [DataMember]。
    【解决方案2】:

    您可以尝试使用 XmlSerializer 代替 DataContractSerializer。 就我而言,我需要更改 global.asax 文件中的默认引擎:

    var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
    xml.UseXmlSerializer = true;
    

    请谨慎执行此操作,因为某些 XML 可能变得无效,例如 - 名称空间,使用 XmlSerializer 应确定如下:

    [XmlNamespaceDeclarations] 
    private XmlSerializerNamespaces xmlns 
    {  
      get {
        var xns = new XmlSerializerNamespaces();
        xns.Add("i", "http://www.w3.org/2001/XMLSchema-instance");
        return xns;
      }    
      set { } 
    }
    

    或者您可以将XmlSerializerFormatAtrribute 设置为您的课程(不适用于我)。 查看 url 头“手动切换到 XmlSerializer”

    【讨论】:

      猜你喜欢
      • 2011-06-28
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      相关资源
      最近更新 更多