在 Visual Studio 生成服务

Generating service in Visual Studio

我是wsdl的初学者。当 Visual Studio 从 wsdl 生成服务引用时。
相关部分:

      <xs:complexType name="FFSCreateOutgoingInvoice">
        <xs:sequence>
          <xs:element name="client" type="xs:string" minOccurs="1"/>
          <xs:element name="center" type="xs:string" minOccurs="1"/>
          <xs:element minOccurs="0" maxOccurs="1" name="emails" type="tns:ArrayOfEmail"/>
          <xs:element name="applicant_login" type="xs:string" minOccurs="1"/>
          <xs:element name="document_type" type="xs:int" minOccurs="1"/>
          <xs:element name="isdoc_data" type="xs:base64Binary" minOccurs="1"/>
          <xs:element name="JID" type="xs:string" minOccurs="0"/>
          <xs:element name="JID_credit" type="xs:string" minOccurs="0"/>
          <xs:element name="contract_number" type="xs:string" minOccurs="1"/>
          <xs:element name="invoice_number" type="xs:string" minOccurs="1"/>
          <xs:element name="invoice_language" type="xs:string" minOccurs="1"/>
          <xs:element name="ext_id_subj_inv_adr" type="xs:string" minOccurs="1"/>
          <xs:element name="ext_id_subj_del_adr" type="xs:string" minOccurs="1"/>
          <xs:element name="attachment_obligation" type="xs:boolean" minOccurs="0"/>
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="ArrayOfEmail">
        <xs:sequence>
          <xs:element minOccurs="0" name="email" type="xs:string"/>
        </xs:sequence>
      </xs:complexType>

生成class

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.4084.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="Namespace")]
    public partial class ArrayOfEmail : object, System.ComponentModel.INotifyPropertyChanged {
        
        private string emailField;
        
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string email {
            get {
                return this.emailField;
            }
            set {
                this.emailField = value;
                this.RaisePropertyChanged("email");
            }
        }
        
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        
        protected void RaisePropertyChanged(string propertyName) {
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null)) {
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }
    }

我在理解类型 ArrayOfEmail 时遇到问题,为什么它不生成数组?而是使用 属性 电子邮件生成 class?

忽略 ArrayOfEmail 名称并关注 XSD 中的声明。您有以下内容:

<xs:element minOccurs="0" maxOccurs="1" name="emails" type="tns:ArrayOfEmail"/>

这声明了一个可以出现零次或一次的 tns:ArrayOfEmail 类型的元素。所以基本上,emails 是一个可选元素,但只有一个存在 ,因为 maxOccurs="1".

如果我们再查看 type="tns:ArrayOfEmail",我们会看到:

  <xs:complexType name="ArrayOfEmail">
    <xs:sequence>
      <xs:element minOccurs="0" name="email" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

这是一个类型,包含一个名为 email 的元素,类型为字符串并带有 minOccurs="0"。同样,这可能会丢失。但是它没有 maxOccurs="1" 那么如果它存在的话它能出现多少次呢? XML Schema specification 是这样说的:

The default value for both the minOccurs and the maxOccurs attributes is 1. Thus, when an element such as comment is declared without a maxOccurs attribute, the element may not occur more than once. Be sure that if you specify a value for only the minOccurs attribute, it is less than or equal to the default value of maxOccurs, i.e. it is 0 or 1. Similarly, if you specify a value for only the maxOccurs attribute, it must be greater than or equal to the default value of minOccurs, i.e. 1 or more. If both attributes are omitted, the element must appear exactly once.

这意味着 emails 实际上不是电子邮件列表,而是存在时只有一个元素,因此您生成的 class 不包含数组,因为模式没有定义数组。 数组需要有maxOccurs="unbounded".

最有可能的情况是,这在某个时间点是一系列电子邮件,但有人将定义更改为只有一封电子邮件。他们没有更改类型名称(这令人困惑)并且可能不想通过重命名 emails 字段并将其作为 email 字符串提升到 [=24 来更改服务合同=] 直接输入,因为这意味着服务合同中断。对于服务器,在这种情况下,具有上述结构的一个电子邮件元素就像一个数组。这样他们就可以保留与实际上是数组时相同的服务器代码。但是对于客户端,生成的代码并没有讲述相同的故事,因为类型不是“数组”。