代码之家  ›  专栏  ›  技术社区  ›  kay.one

“服务引用”和“Web引用”之间的不同行为

  •  3
  • kay.one  · 技术社区  · 17 年前

    我有如下定义的WCF端点暴露,

    <service name="MyApp.Server.Endpoint.Orange" behaviorConfiguration="MyTio.Server.Endpoint.OrangeBehavior">
      <endpoint address="" binding="basicHttpBinding" contract="Host.Server.Contract.IMyAppApi" bindingNamespace="http://host.com/myapp">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
    

    当我在.NET 3.5中添加“服务引用”时,我们在代理中得到了以下类,这是非常好的:

        [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="GetMemberBillersRequest", Namespace="http://schemas.datacontract.org/2004/07/Contract.MemberBillers")]
    [System.SerializableAttribute()]
    public partial class GetMemberBillersRequest : WCFClient.MyRequest {
    
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private int ApplicationIdField;
    
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        private int ProductIdField;
    
        [System.Runtime.Serialization.DataMemberAttribute()]
        public int ApplicationId {
            get {
                return this.ApplicationIdField;
            }
            set {
                if ((this.ApplicationIdField.Equals(value) != true)) {
                    this.ApplicationIdField = value;
                    this.RaisePropertyChanged("ApplicationId");
                }
            }
        }
    
        [System.Runtime.Serialization.DataMemberAttribute()]
        public int ProductId {
            get {
                return this.ProductIdField;
            }
            set {
                if ((this.ProductIdField.Equals(value) != true)) {
                    this.ProductIdField = value;
                    this.RaisePropertyChanged("ProductId");
                }
            }
        }
    }
    

    问题是在.NET 2.0中添加对同一服务的引用时

    您将获得同一合同的以下代理:

        [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://schemas.datacontract.org/2004/07/Contract.MemberBillers")]
    public partial class GetMemberBillersRequest : MyRequest {
    
        private int applicationIdField;
    
        private bool applicationIdFieldSpecified;
    
        private int productIdField;
    
        private bool productIdFieldSpecified;
    
        /// <remarks/>
        public int ApplicationId {
            get {
                return this.applicationIdField;
            }
            set {
                this.applicationIdField = value;
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public bool ApplicationIdSpecified {
            get {
                return this.applicationIdFieldSpecified;
            }
            set {
                this.applicationIdFieldSpecified = value;
            }
        }
    
        /// <remarks/>
        public int ProductId {
            get {
                return this.productIdField;
            }
            set {
                this.productIdField = value;
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public bool ProductIdSpecified {
            get {
                return this.productIdFieldSpecified;
            }
            set {
                this.productIdFieldSpecified = value;
            }
        }
    }
    

    除了通过.NET 2.0生成的代理具有两个附加字段外,这两个字段都是相同的:

    ProductIDFields已指定,ApplicationIDFields已指定。这两个字段的问题是,如果您不手动将它们设置为true,它们对应的字段(ApplicationId、ProductId)将不会序列化并传递给服务器!

    有人能给我解释一下这里发生了什么事吗?

    编辑:

    我发现这只发生在int类型上,而不是字符串上! 这是此操作的数据协定

    [DataContract]
    public class GetMemberBillersRequest : MyRequest
    {
        [DataMember]
        public int ApplicationId { get; set; }
    
        [DataMember]
        public int ProductId { get; set; }
    }
    
    2 回复  |  直到 17 年前
        1
  •  3
  •   John Saunders    17 年前

    这是预期的行为,自.NET1.0以来一直如此。您将看到,对于模式中可选的任何基元类型,可以是use=“optional”属性,也可以是minOccurs=“0”元素。

    如果缺少属性或元素,则无法将生成的属性设置为null。相反,在这种情况下,*指定的字段设置为false。在决定是否存在“真实”字段之前,请检查该字段。

    类似地,如果要设置main属性,则必须将*specified属性设置为true,否则它将不会被发送。


    我相信你知道,但我要为未来的读者添加这一点:是的,现在有可为空的类型。然而,随着WCF的出现,ASMXWeb服务的开发速度大大减慢。原语类型从未实现过可为null的属性,这并不奇怪。

    此外,请注意: Microsoft: ASMX Web Services are a “Legacy Technology”

        2
  •  1
  •   softveda    17 年前

    推荐文章