WCF 服务代理未设置“FieldSpecified"财产 [英] WCF service proxy not setting "FieldSpecified" property

查看:29
本文介绍了WCF 服务代理未设置“FieldSpecified"财产的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 WCF DataContract,如下所示:

I've got a WCF DataContract that looks like the following:

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 中添加对此服务的引用时,会生成此代理代码:

When I add a reference to this service in Visual Studio, this proxy code is generated:

/// <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 生成支持属性外,还会生成一个附加的 Specified 属性.一切都很好,除了当我执行以下操作时:

As you can see, besides generating a backing property for EditDate, an additional <propertyname>Specified property is generated. All good, except that when I do the following:

DataContractBase myDataContract = new DataContractBase();
myDataContract.EditDate = DateTime.Now;

new MyServiceClient.Update(new UpdateRequest(myDataContract));

EditDate 没有被服务的端点接收(没有出现在传输的 XML 中).

the EditDate was not getting picked up by the endpoint of the service (does not appear in the transmitted XML).

我调试了代码,发现虽然我设置了 EditDate,但是 EditDateSpecified 属性并没有像我一样设置为 true会期待;因此,XML 序列化程序忽略了 EditDate 的值,即使它被设置为一个有效值.

I debugged the code and found that, although I was setting EditDate, the EditDateSpecified property wasn't being set to true as I would expect; hence, the XML serializer was ignoring the value of EditDate, even though it's set to a valid value.

为了快速修改,我将 EditDate 属性修改为如下所示:

As a quick hack I modified the EditDate property to look like the following:

   /// <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");
        }
    }

现在代码按预期工作,但当然每次我重新生成代理时,我的修改都会丢失.我可以将调用代码更改为以下内容:

Now the code works as expected, but of course every time I re-generate the proxy, my modifications are lost. I could change the calling code to the following:

DataContractBase myDataContract = new DataContractBase();
myDataContract.EditDate = DateTime.Now;
myDataContract.EditDateSpecified = true;

new MyServiceClient.Update(new UpdateRequest(myDataContract));

但这似乎也是一种黑客式的浪费时间.

but that also seems like a hack-ish waste of time.

最后,我的问题是:有没有人对如何克服 Visual Studio 服务代理生成器的这种不直观(和 IMO 损坏)行为提出建议,或者我只是遗漏了什么?

So finally, my question: does anyone have a suggestion on how to get past this unintuitive (and IMO broken) behavior of the Visual Studio service proxy generator, or am I simply missing something?

推荐答案

这可能有点不直观(也让我措手不及!) - 但这是处理可能或不可能的元素的唯一正确方法在您的 XML 架构中指定.

It might be a bit unintuitive (and caught me off guard and reeling, too!) - but it's the only proper way to handle elements that might or might not be specified in your XML schema.

而且您必须自己设置 xyzSpecified 标志似乎也有悖常理——但最终,这给了您更多的控制权,而 WCF 就是关于 SOA 的四个原则非常明确和清楚地说明您的意图.

And it also might seem counter-intuitive that you have to set the xyzSpecified flag yourself - but ultimately, this gives you more control, and WCF is all about the Four Tenets of SOA of being very explicit and clear about your intentions.

所以基本上 - 就是这样,习惯它:-) 没有办法超越"这种行为 - 这是 WCF 系统的设计方式,也是有充分理由的.

So basically - that's the way it is, get used to it :-) There's no way "past" this behavior - it's the way the WCF system was designed, and for good reason, too.

您始终可以做的是捕获并处理 this.RaisePropertyChanged("EditDate"); 事件并在该事件的事件处理程序中设置 EditDateSpecified 标志.

What you always can do is catch and handle the this.RaisePropertyChanged("EditDate"); event and set the EditDateSpecified flag in an event handler for that event.

这篇关于WCF 服务代理未设置“FieldSpecified"财产的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆