Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF服务代理未设置";“指定字段”;财产_C#_.net_Wcf - Fatal编程技术网

C# WCF服务代理未设置";“指定字段”;财产

C# WCF服务代理未设置";“指定字段”;财产,c#,.net,wcf,C#,.net,Wcf,我有一个WCFDataContract,看起来如下所示: namespace MyCompanyName.Services.Wcf { [DataContract(Namespace = "http://mycompanyname/services/wcf")] [Serializable] public class DataContractBase { [DataMember] public DateTime EditDate { get; set; }

我有一个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...
  }
}
DataContractBase myDataContract = new DataContractBase();
myDataContract.EditDate = DateTime.Now;

new MyServiceClient.Update(new UpdateRequest(myDataContract));
   /// <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中添加对此服务的引用时,将生成以下代理代码:

/// <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
(未显示在传输的XML中)

我调试了代码,发现尽管我正在设置
EditDate
,但
EditDateSpecified
属性并没有像我预期的那样设置为
true
;因此,XML序列化程序忽略了
EditDate
的值,即使它被设置为有效值

作为一种快速攻击,我修改了
EditDate
属性,使其看起来如下所示:

namespace MyCompanyName.Services.Wcf
{
  [DataContract(Namespace = "http://mycompanyname/services/wcf")]
  [Serializable]
  public class DataContractBase
  {
    [DataMember]
    public DateTime EditDate { get; set; }

    // code omitted for brevity...
  }
}
DataContractBase myDataContract = new DataContractBase();
myDataContract.EditDate = DateTime.Now;

new MyServiceClient.Update(new UpdateRequest(myDataContract));
   /// <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));
但这看起来也像是在浪费时间


最后,我的问题是:有人对如何克服VisualStudio服务代理生成器的这种不直观(而且我认为是坏的)行为有什么建议吗?还是我只是缺少了一些东西?

这可能有点不直观(也让我措手不及,不知所措!)-但这是处理XML模式中可能指定或可能未指定的元素的唯一正确方法

您必须自己设置
xyzSpecified
标志,这似乎也有违直觉,但最终,这会让您拥有更多的控制权,而WCF的目的就是非常明确和清楚地表达您的意图

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

您总是可以捕获并处理
this.RaisePropertyChanged(“EditDate”)事件,并在该事件的事件处理程序中设置
EditDateSpecified
标志。

, 请忽略我之前的回答,我正在解释如何吸鸡蛋。我投票决定删除它们

您能告诉我您使用的是哪个版本的Visual Studio吗

在VS2005客户机中-在生成的代码中,我获得指定的
标志,但在值更改时没有引发任何事件。要传递数据,我必须设置
指定的
标志

在VisualWebDeveloper2008Express客户端中-在生成的代码中,我没有得到指定的
标志,但我确实得到了值更改时的事件

在我看来,这个功能已经发展,WebDev2008更接近您所追求的,并且更直观,因为一旦设置了值,您就不需要设置标志

试试这个

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

这应该省略
EditDateSpecified
属性,因为该字段是按要求指定的

这里有一个简单的项目,可以修改生成的WCF代码中可选属性的设置器,以便在设置相关值时自动将*指定标志设置为true

显然,在某些情况下,您需要手动控制*指定的标志,因此我并不向所有人推荐它,但在大多数简单的用例中,*指定的标志只是一个额外的麻烦,自动设置它们可以节省时间,而且通常更直观


请注意,如果您控制Web服务发布点,这里的另一个答案将为您解决这个问题。然而,我通常不控制Web服务发布,而只是使用一个,并且必须在一些简单的软件中处理*指定的标志,我希望这是自动化的。因此,此工具。

将代理类属性更改为可空类型

例:

布尔?证实


约会时间?checkDate

您可以使用扩展类来“autospecify”(绑定更改处理程序事件),而不是更改自动生成代码的设置程序。这可能有两种实现——一种是“惰性”实现(
Autospecify
),它使用反射来查找基于属性名指定的字段,而不是在某种类型的switch语句(如
Autonotify
)中列出每个类的所有字段:

懒惰的 然后每个类自己定义行为:

public partial class MyRandomClass: IAutoNotifyPropertyChanged
{
    public void WhenPropertyChanges(string propertyName)
    {
        switch (propertyName)
        {
            case "field1": this.field1Specified = true; return;
            // etc
        }
    }
}
当然,这样做的缺点是,属性名的神奇字符串使重构变得困难,您可以通过
表达式
解析?

了解更多信息 在MSDN上

在她的回答中,Shreesha解释说:

“指定”字段仅在结构的可选参数上生成。(int、datetime、decimal等)。所有这些变量都将生成具有指定名称的附加变量

这是一种了解客户机和服务器之间是否真的传递了参数的方法

更详细地说,如果不传递一个可选整数,那么它的dafault值仍然是0。您如何区分此值与实际传递的值为0的值?“指定”字段让您知道是否传递了可选整数。如果“指定”字段为false,则不会传递该值。如果为true,则传递整数

因此,从本质上说,设置这些字段的唯一方法是手动设置它们,如果对于已设置的字段,这些字段没有设置为true,那么该字段将在web服务调用的SOAP消息中丢失


我最后做的是构建一个方法来循环对象的所有成员,如果已经设置了属性,并且指定了一个名为name\u的属性,则将其设置为true。

如果有人忘记了指定的XYZ,则生成警告是否会违反规则?同意这是答案,不同意这是唯一的方法/好的设计。这是垃圾设计。他们需要提供一个选项,以便在简单用例的属性设置器中自动设置这些属性。将
[XMLSerializerFormat]
添加到服务的属性中:如果您从@MustafaMagdy的注释中复制/粘贴,请检查此选项——如果我们在本地代理中添加该属性,则为
[XMLSerializerFormat]
(请注意此情况),它不会被覆盖吗