WCF 不会序列化所有属性

Posted

技术标签:

【中文标题】WCF 不会序列化所有属性【英文标题】:WCF doesn't serialize all properties 【发布时间】:2012-01-08 20:35:50 【问题描述】:

我正在使用已在 VS2010 中作为服务引用导入的 SOAP 服务。我使用服务提供的请求对象调用其中一项服务。我遇到的问题是并非对象的所有属性都被序列化,或者不是通过网络发送。请求对象如下所示:

var serviceRequest = new UpdateRequest
    StoreId = request.StoreId,
    Id = request.Id,
    Status = (Status)Enum.Parse(typeof(Status), request.myStatus.ToString()),
    parameters = request.Parameters,
    validFrom = request.ValidFrom.Value,
    validFromSpecified = request.ValidFromSpecified
;

这是通过网络发送的内容。我已经用wireshark捕获了它

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<updateStore xmlns="http://localhost.service.com/">
    <StoreRequest>
    <StoreId>1234</StoreId>
    <validFrom>2011-11-29T00:00:00</validFrom>
    <parameters>
        <param1>true</param1>
    </parameters>
    </StoreRequest>
</updateStore>
</s:Body>
</s:Envelope>

Id 和 Status 这两个参数没有发送到服务,我就是不知道为什么。正在设置值,并且 WSDL 生成的属性是公共的,并且具有与正在序列化的属性相同的序列化属性。

任何帮助将不胜感激。

编辑---- 更新了服务参考生成代码

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.233")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://myservice.com/")]
public partial class StoreUpdateRequest : object,        
System.ComponentModel.INotifyPropertyChanged 
    private long StoreIdField;        
    private long IdField;        
    private bool IdFieldSpecified;        
    private Status StatusField;        
    private bool StatusFieldSpecified;        
    private long storeIdField;        
    private bool storeIdFieldSpecified;        
    private System.DateTime validFromField;        
    private bool validFromFieldSpecified;        
    private System.DateTime validToField;        
    private bool validToFieldSpecified;        
    private technicalParameters parametersField;        
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Order=0)]
    public long StoreId 
        get 
            return this.StoreIdField;
        
        set 
            this.StoreIdField = value;
            this.RaisePropertyChanged("StoreId");
        
    

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Order=1)]
    public long Id 
        get 
            return this.IdField;
        
        set 
            this.IdField = value;
            this.RaisePropertyChanged("Id");
        
    

【问题讨论】:

也许是一个显而易见的问题,ID 和状态是什么类型?他们的类型是公开的吗? 你能发布你的 UpdateRequest 的定义吗? Id 和 Status 也必须是属性(使用 get() 和 set()),而不仅仅是字段... 他们是public 吗?他们有 getset 吗?他们标记为[Obsolete] 吗?或[XmlIgnore] ?有ShouldSerializeId() 方法吗?还是IdSpecified 属性?这里有很多未知数,看到类型会有所帮助。如果这是[DataContract],他们有[DataMember(...)] 您的UpdateRequest 中是否还有其他属性(如ValidFromSpecified)也伴随着同名的bool 属性+Specified?在这种情况下 - 您必须(property)Specified 值设置为 true - 否则,该属性将不会被序列化 - 无论它是否具有分配的值。 【参考方案1】:

问题已解决。错误在于 SOAP 服务已更新,并且某些属性现在是可选的。 当一个字段/属性说 XX 在 SOAP 消息中被标记为可选时,WCF 会创建一个相应的额外 XXIsSpecified 属性,当该属性必须设置为 trueXX 值已设置。否则 WCF 将不会序列化或发送该属性。

有多种方法可以查看属性是否设置为可选。

在生成的 Reference.cs 文件中,每个可选项都有一个对应的 IsSpecified 属性,如下所示:private System.DateTime validFromField; private bool validFromFieldSpecified;

您可以使用soapUI查看和测试wsdl

使用 chrome 或其他浏览器浏览到 wsdl,查看元素是否具有 minoccurs 属性。如果它在那里并且它的值为 0,那么它是可选的。像这样&lt;xs:element minOccurs="0" name="validFrom" type="xs:dateTime"/&gt;

【讨论】:

以上是关于WCF 不会序列化所有属性的主要内容,如果未能解决你的问题,请参考以下文章

再说WCF Data Contract KnownTypeAttribute

WCF 数据服务,序列化实体框架部分类的附加属性

WCF 反序列化中的 XmlException:“名称不能以 '<' 开头”-在自动属性支持字段中

如何在 WCF 中使用自定义序列化或反序列化来强制在 datacontact 的每个属性上创建一个新实例?

WCF+Nhibernate循环引用导致序列化的问题

替换 WCF 默认 JSON 序列化