如何使用 WCF 服务引用来使用 RPC 样式的 Web 服务?
Posted
技术标签:
【中文标题】如何使用 WCF 服务引用来使用 RPC 样式的 Web 服务?【英文标题】:How to Consume an RPC-Style Web Service with a WCF Service Reference? 【发布时间】:2013-11-21 13:43:01 【问题描述】:我正在编写一个调用 Web 服务对客户端进行身份验证的 C# 客户端。我使用添加服务引用将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 为空。
【问题讨论】:
你在哪一行得到这个错误? 我试图显示 result.message 的最后一行。NullReferenceException
的几乎所有情况都是相同的。请参阅“What is a NullReferenceException in .NET?”获取一些提示。显然,如果returnResult
为空,那么returnResult.message
将抛出NullReferenceException
。
所有这些代码,没有 NRE 的概念,也没有如何调试它们。嗯。
所以textBoxResult
或result
是null
。但是您显示的 SOAP 结果不是空的,并且填充了 message
属性...我会尝试使用 var result = client.authenticateAccess(details, memKey);
而不是您在上面的声明和调用,并使用调试器确保 result
确实为空。顺便说一句,您是如何使用嗅探器获得 SOAP 结果的?
【参考方案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 的意见和指导。
【讨论】:
以上是关于如何使用 WCF 服务引用来使用 RPC 样式的 Web 服务?的主要内容,如果未能解决你的问题,请参考以下文章