#c# #wsdl
Вопрос:
Я новичок в 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>
Сгенерированный класс
[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, почему он не генерирует массив? Вместо этого создайте класс с электронной почтой свойства?
Ответ №1:
Игнорируйте 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>
Это тип, который содержит элемент on с именем email
типа string и with minOccurs="0"
. Так что, опять же, этого может не хватать. Но его нет maxOccurs="1"
, так сколько же раз он может появиться, если он присутствует? В спецификации XML-схемы говорится следующее:
Значение по умолчанию для атрибутов minOccurs и maxOccurs равно 1. Таким образом, когда такой элемент, как комментарий, объявляется без атрибута maxOccurs, элемент может встречаться не более одного раза. Убедитесь, что если вы укажете значение только для атрибута minOccurs, оно будет меньше или равно значению maxOccurs по умолчанию, т. е. равно 0 или 1. Аналогично, если вы указываете значение только для атрибута maxOccurs, оно должно быть больше или равно значению minOccurs по умолчанию, т. е. 1 или более. Если оба атрибута опущены, элемент должен появиться ровно один раз.
Это означает emails
, что на самом деле это не список электронных писем, а только один элемент, когда он присутствует, поэтому созданный вами класс не содержит массива, поскольку схема не определяет массив. Массивы должны быть maxOccurs="unbounded"
.
Скорее всего, здесь происходит то, что в какой-то момент времени это был массив электронных писем, но кто-то изменил определение только на одно электронное письмо. Они не изменили имя типа (что сбивает с толку) и, вероятно, не хотели изменять контракт на обслуживание emails
, также переименовав поле и переведя его как email
строку FFSCreateOutgoingInvoice
непосредственно в тип, потому что это означало бы разрыв контракта на обслуживание. Для сервера в этом контексте один элемент электронной почты, представленный в приведенной выше структуре, аналогичен массиву из одного. Таким образом, они, вероятно, могли бы сохранить тот же код сервера, который у них был, когда это был на самом деле массив. Но для клиента сгенерированный код не рассказывает ту же историю, потому что типы не являются «массивами».