如何使用 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 的概念,也没有如何调试它们。嗯。 所以textBoxResultresultnull。但是您显示的 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 服务?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 wcf 的 .net Web 服务创建安全的 SOAP 主体?

在 ClassLibrary 中使用 WCF 服务时出错

在类库中使用 WCF 服务时出错

Web API RPC 与 WCF 和 JSON [重复]

在 WCF 中实现 JSON-RPC

WCF引用服务和直接用接口的区别