WCF服务代理未设置“FieldSpecified”属性如何解决?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (115)

我有一个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破坏)行为的建议,还是我简单地错过了一些东西?

提问于
用户回答回答于

这可能有点不直观(并且也让我无法防范和re!!) - 但它是处理可能或可能不会在XML模式中指定的元素的唯一正确方法。

而且,必须自己设置xyzSpecified标志,这看起来可能是反直觉的- 但最终,这会给更多的控制权,而WCF的所有关于SOA四条原则都是非常明确和清楚意图。

所以基本上 - 就是这样,习惯它:-)没有办法“过去”这种行为 - 这是WCF系统设计的方式,也有很好的理由。

你总能做的就是捕捉和处理this.RaisePropertyChanged("EditDate");事件,并EditDateSpecified在该事件的事件处理程序中设置标志。

用户回答回答于

尝试这个

[DataMember(IsRequired=true)]
public DateTime EditDate { get; set; }

这应该省略该EditDateSpecified属性,因为该字段是根据需要指定的

扫码关注云+社区