Как использовать веб-сервис в стиле RPC со ссылкой на сервис WCF?

Я пишу клиент C#, который вызывает веб-сервис для аутентификации клиентов. Я использовал add service reference для добавления файла wsdl в мой проект, и прокси-класс сгенерирован успешно.

Я создаю новые экземпляры объектов, которые будут использоваться следующим образом:

authenticateAccessPortTypeClient client = new authenticateAccessPortTypeClient();
authDetails details = new authDetails();
returnResult result = new returnResult();

Это мой код, когда пользователь должен пройти аутентификацию:

// This is details that needs to be passed in the header of the SOAP Envelope
details.key = "some key as string";
details.mode = "the mode as string";

// This is a parameter that is passed in the body of the SOAP Envelope
string memKey = "the member key as string";

result = client.authenticateAccess(details, memKey);

textBoxResult.Text = result.message;

Мой мыльный ответ выглядит так:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:example="www.example.com">
   <soapenv:Header/>
   <soapenv:Body>
      <example:authenticateAccessResponse>
         <result>
            <message>some string</message>
         </result>
      </example:authenticateAccessResponse>
   </soapenv:Body>
</soapenv:Envelope>

И returnResults выглядит следующим образом в сгенерированном прокси-классе:

public partial class returnResult : object, System.ComponentModel.INotifyPropertyChanged {

    private string messageField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
    public string message {
        get {
            return this.messageField;
        }
        set {
            this.messageField = value;
            this.RaisePropertyChanged("message");
        }
    }

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

Я продолжаю получать сообщение об ошибке: ссылка на объект не установлена ​​на экземпляр объекта и returnResult имеет значение null.

1 ответ

Решение

После долгих поисков и поисков, а также благодаря пользователям, прокомментировавшим этот пост, я решил свою проблему.

Фактическая проблема была не на стороне клиента, а на самом файле WSDL. Я изменил стиль привязки файла WSDL, чтобы использовать документ с литералом. Структура типов моего wsdl-файла была изменена на следующую:

<xsd:element name="nameOfType">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="1" maxOccurs="1" name="element1" type="xsd:string"/>
        <xsd:element minOccurs="1" maxOccurs="1" name="element2" type="xsd:string"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

Тег complexType должен быть заключен в другой тег элемента, чтобы использовать перенос букв, а атрибут name устанавливается в первом элементе.

Теги сообщения затем изменились на:

<wsdl:message name="messageName">
    <wsdl:part name="nameOfType" element="tns:nameOfType"/>
</wsdl:message>

* Обратите внимание на атрибут элемента вместо атрибута типа

И привязка выглядит так:

<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="nameOfWebMethod">
  <soap:operation soapAction="nameOfWebMethod"/>
  <wsdl:input>
    <soap:body use="literal"
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:youNamespace:nameOfService"/>
    <soap:header message="tns:messageName" part="nameOfType" use="literal"/>
  </wsdl:input>
  <wsdl:output>
    <soap:body use="literal"
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:youNamespace:nameOfService"/>
  </wsdl:output>
</wsdl:operation>

Спасибо @John Saunders & @Roy Dictus за ваш вклад и руководство.

Другие вопросы по тегам