C# 如何使用带有WCF服务引用的RPC样式的Web服务?
我正在编写一个C#客户端,它调用web服务来验证客户端。我使用AddServiceReference将wsdl文件添加到我的项目中,并成功生成了代理类 我正在创建新的对象实例,这些对象将按如下方式使用:C# 如何使用带有WCF服务引用的RPC样式的Web服务?,c#,wcf,soap,rpc,soap-rpc-encoded,C#,Wcf,Soap,Rpc,Soap Rpc Encoded,我正在编写一个C#客户端,它调用web服务来验证客户端。我使用AddServiceReference将wsdl文件添加到我的项目中,并成功生成了代理类 我正在创建新的对象实例,这些对象将按如下方式使用: authenticateAccessPortTypeClient client = new authenticateAccessPortTypeClient(); authDetails details = new authDetails(); returnResult result = new
authenticateAccessPortTypeClient client = new authenticateAccessPortTypeClient();
authDetails details = new authDetails();
returnResult result = new returnResult();
<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>
<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>
当用户需要进行身份验证时,这是我的代码:
// 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;
我的soap响应如下所示:
authenticateAccessPortTypeClient client = new authenticateAccessPortTypeClient();
authDetails details = new authDetails();
returnResult result = new returnResult();
<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>
<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>
一些绳子
在生成的代理类中,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));
}
}
}
public分部类returnResult:object,System.ComponentModel.INotifyPropertyChanged{
私有字符串消息字段;
///
[System.Xml.Serialization.xmlementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified,Order=0)]
公共字符串消息{
得到{
返回此.messageField;
}
设置{
this.messageField=值;
此.RaisePropertyChanged(“消息”);
}
}
公共事件System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
受保护的void RaisePropertyChanged(字符串propertyName){
System.ComponentModel.PropertyChangedEventHandler propertyChanged=this.propertyChanged;
如果((propertyChanged!=null)){
propertyChanged(这是新的System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
我不断得到错误:对象引用未设置为对象的实例,返回结果为空。经过大量的谷歌搜索和调试,感谢对本文发表评论的用户,我解决了我的问题 实际的问题不在客户端,而是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标记需要包装在另一个元素标记中,才能使用文字包装,因为名称属性是在第一个元素中设置的
消息标签随后更改为:
<wsdl:message name="messageName">
<wsdl:part name="nameOfType" element="tns:nameOfType"/>
</wsdl:message>
*注意元素属性而不是类型属性
绑定方式如下所示:
authenticateAccessPortTypeClient client = new authenticateAccessPortTypeClient();
authDetails details = new authDetails();
returnResult result = new returnResult();
<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>
<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为您提供的输入和指导。您在哪一行得到了错误?我试图显示结果的最后一行。消息。几乎所有
NullReferenceException
的情况都是相同的。有关提示,请参阅“”。显然,如果returnResult
为空,那么returnResult.message
将抛出NullReferenceException
。所有这些代码都没有NRE的概念,也没有如何调试它们。嗯,所以textBoxResult
或result
是null
。但是您显示的SOAP结果不是空的,消息
属性被填充。。。我会尝试var result=client.authenticateAccess(详细信息,memKey)代码>而不是上面的声明和调用,使用调试器确保result
确实为null。顺便问一下,你是如何使用嗅探器得到SOAP结果的?