简体   繁体   中英

Generating service in Visual Studio

I am beginner, in wsdl. When Visual Studio generate service reference from wsdl.
Relevant part:

      <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>

Generated 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));
            }
        }
    }

I am having problem understand type ArrayOfEmail, why it does not generate array? Instead generate class with property email?

Ignore the ArrayOfEmail name and focus on the declarations in your XSD. You have the following:

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

This declares an element of type tns:ArrayOfEmail that can occur zero or one time. So basically, emails is an optional element, but just one when present , because maxOccurs="1" .

If we then look at type="tns:ArrayOfEmail" , we see:

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

This is a type that contains on element named email of type string and with minOccurs="0" . So again, this can be missing. But it has no maxOccurs="1" so how many times can it show up if it is present? The XML Schema specification says this:

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, ie 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, ie 1 or more. If both attributes are omitted, the element must appear exactly once.

That means emails is not actually a list of emails but just one element when present , thus your generated class does not contain an array, because the schema does not define an array. Arrays need to have maxOccurs="unbounded" .

Most likely, what's happening here is that this was at some point in time an array of emails but someone changed the definition to just one email. They didn't change the type name (which is confusing) and probably didn't want to change the service contract by renaming the emails field also and lift it as the email string into the FFSCreateOutgoingInvoice type directly, because that would mean a break in the service contract. For the server, in this context, one email element provided with the structure above is just like an array of one. This way they could probably keep the same server code that they had when this was actually an array. But for the client, the code generated doesn't tell the same story because the types are not "array".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM