Как использовать веб-сервис в стиле 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 за ваш вклад и руководство.