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
吗?他们有 get
和 set
吗?他们标记为[Obsolete]
吗?或[XmlIgnore]
?有ShouldSerializeId()
方法吗?还是IdSpecified
属性?这里有很多未知数,看到类型会有所帮助。如果这是[DataContract]
,他们有[DataMember(...)]
等
您的UpdateRequest
中是否还有其他属性(如ValidFromSpecified
)也伴随着同名的bool
属性+Specified
?在这种情况下 - 您必须将 (property)Specified
值设置为 true - 否则,该属性将不会被序列化 - 无论它是否具有分配的值。
【参考方案1】:
问题已解决。错误在于 SOAP 服务已更新,并且某些属性现在是可选的。 当一个字段/属性说 XX 在 SOAP 消息中被标记为可选时,WCF 会创建一个相应的额外 XXIsSpecified 属性,当该属性必须设置为 true 时XX 值已设置。否则 WCF 将不会序列化或发送该属性。
有多种方法可以查看属性是否设置为可选。
在生成的 Reference.cs 文件中,每个可选项都有一个对应的 IsSpecified 属性,如下所示:private System.DateTime validFromField;
private bool validFromFieldSpecified;
您可以使用soapUI查看和测试wsdl
使用 chrome 或其他浏览器浏览到 wsdl,查看元素是否具有 minoccurs 属性。如果它在那里并且它的值为 0,那么它是可选的。像这样<xs:element minOccurs="0" name="validFrom" type="xs:dateTime"/>
【讨论】:
以上是关于WCF 不会序列化所有属性的主要内容,如果未能解决你的问题,请参考以下文章
再说WCF Data Contract KnownTypeAttribute
WCF 反序列化中的 XmlException:“名称不能以 '<' 开头”-在自动属性支持字段中