我有一个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
;因此,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破坏)的行为有什么建议,或者我只是遗漏了什么?
发布于 2009-11-05 21:34:34
这可能有点不直观(也让我猝不及防!)--但这是处理XML模式中可能指定的或可能没有指定的元素的唯一正确方法。
而且,你必须自己设置xyzSpecified
标志,这似乎也是违反直觉的--但最终,这给了你更多的控制权,而Four Tenets of SOA就是非常明确和清楚地表明你的意图。
所以基本上-这就是它的方式,习惯它:-)没有办法“过去”这个行为-这是WCF系统设计的方式,也有很好的理由。
您始终可以做的是捕获和处理this.RaisePropertyChanged("EditDate");
事件,并在该事件的事件处理程序中设置EditDateSpecified
标志。
发布于 2010-01-12 14:36:40
尝尝这个
[DataMember(IsRequired=true)]
public DateTime EditDate { get; set; }
此操作应忽略EditDateSpecified
属性,因为该字段是按必填项指定的
发布于 2009-11-06 01:27:49
伊恩,请忽略我之前的回答,解释如何吸鸡蛋。我已经投票决定删除它们。
您能告诉我您使用的是哪个版本的Visual Studio吗?
在VS2005客户端中-在生成的代码中,我得到了<property>Specified
标志,但在值更改时没有引发任何事件。要传递数据,我必须设置<property>Specified
标志。
在Visual Web Developer2008Express客户端中-在生成的代码中,我没有得到任何<property>Specified
标志,但我确实得到了值更改时的事件。
在我看来,这个功能已经发生了变化,Web Dev 2008更接近你想要的,也更直观,因为一旦设置了值,你就不需要设置标志了。
鲍西
https://stackoverflow.com/questions/1680356
复制相似问题