我有一个WCF DataContract
,如下所示:
namespace MyCompanyName.Services.Wcf
{
[DataContract(Namespace = "http://mycompanyname/services/wcf")]
[Serializable]
public class DataContractBase
{
[DataMember]
public DateTime EditDate { get; set; }
// code omitted for brevity...
}
}
当我在Visual Studio中添加对此服务的引用时,将生成以下代理代码:
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://mycompanyname/services/wcf")]
public partial class DataContractBase : object, System.ComponentModel.INotifyPropertyChanged {
private System.DateTime editDateField;
private bool editDateFieldSpecified;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public System.DateTime EditDate {
get {
return this.editDateField;
}
set {
this.editDateField = value;
this.RaisePropertyChanged("EditDate");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool EditDateSpecified {
get {
return this.editDateFieldSpecified;
}
set {
this.editDateFieldSpecified = value;
this.RaisePropertyChanged("EditDateSpecified");
}
}
// code omitted for brevity...
}
如您所见,除了生成
EditDate
的后备属性外,还生成了另一个<propertyname>Specified
属性。一切都很好,除了在执行以下操作时:DataContractBase myDataContract = new DataContractBase();
myDataContract.EditDate = DateTime.Now;
new MyServiceClient.Update(new UpdateRequest(myDataContract));
服务的端点未获取
EditDate
(未出现在传输的XML中)。我调试了代码,发现尽管设置了
EditDate
,但EditDateSpecified
属性并未像我期望的那样设置为true
。因此,即使XML序列化器设置为有效值,它也忽略了EditDate
的值。作为一个快速技巧,我将
EditDate
属性修改为如下所示: /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public System.DateTime EditDate {
get {
return this.editDateField;
}
set {
this.editDateField = value;
// hackhackhack
if (value != default(System.DateTime))
{
this.EditDateSpecified = true;
}
// end hackhackhack
this.RaisePropertyChanged("EditDate");
}
}
现在代码可以按预期工作,但是当然每次我重新生成代理时,所做的修改都会丢失。我可以将调用代码更改为以下内容:
DataContractBase myDataContract = new DataContractBase();
myDataContract.EditDate = DateTime.Now;
myDataContract.EditDateSpecified = true;
new MyServiceClient.Update(new UpdateRequest(myDataContract));
但这似乎也浪费时间。
所以最后,我的问题是:是否有人对如何摆脱Visual Studio服务代理生成器的这种不直观(且IMO损坏)的行为提出建议,或者我只是缺少什么?
最佳答案
这可能有点不直观(并且也使我措手不及!)-但这是处理XML模式中可能指定或可能未指定的元素的唯一正确方法。
而且,您必须自己设置xyzSpecified
标志似乎也很违反直觉-但是最终,这给了您更多的控制权,WCF就是关于Four Tenets of SOA非常明确和清楚您的意图的全部内容。
因此,基本上-这就是它的方式,请习惯它:-)不可能“粘贴”此行为-这是WCF系统的设计方式,也是有充分理由的。
您始终可以做的是捕获并处理this.RaisePropertyChanged("EditDate");
事件,并在该事件的事件处理程序中设置EditDateSpecified
标志。
关于c# - WCF服务代理未设置 “FieldSpecified”属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1680356/