C# - 将 header 信息传递给 SOAP 网络服务客户端

C# - Passing header information to SOAP webservice client

我在 Visual Studio 的 C# 项目中添加了一个 SOAP web 服务作为服务引用,但是要么我做错了什么,要么它似乎没有被正确解析。 WSDL 明确公开了一个 header 来传递身份验证令牌(我可以从另一个方法中获取),而这个 header 在我需要使用的方法 (getDeviceInfoRequest) 中被引用。下面的相关 WSDL 位:

<wsdl:message name="getDeviceInfoRequest">
<wsdl:part name="Auth" type="types:Auth"/>
<wsdl:part name="DeviceName" type="xsd:string"/>
</wsdl:message>

<wsdl:operation name="getDeviceInfo">
<wsdl:input name="getDeviceInfoRequest" message="tns:getDeviceInfoRequest"/>
<wsdl:output name="getDeviceInfoResponse" message="tns:getDeviceInfoResponse"/>
</wsdl:operation>

<wsdl:operation name="getDeviceInfo">
<soap:operation soapAction="" style="rpc"/>
<wsdl:input name="getDeviceInfoRequest">
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:NetworkService" use="encoded" parts="DeviceName"/>
<soap:header encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:NetworkService" use="encoded" message="tns:getDeviceInfoRequest" part="Auth"/>
</wsdl:input>
<wsdl:output name="getDeviceInfoResponse">
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:NetworkService" use="encoded"/>
</wsdl:output>
</wsdl:operation>

<xsd:complexType name="Auth">
<xsd:sequence>
<xsd:element name="token" nillable="false" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>

但是,当我在 Visual Studio(参考 -> 添加服务参考)中生成客户端代理时,无法将令牌传递给 getDeviceInfoRequest 方法,因为它是使用单个参数生成的(DeviceName ).这是 WSDL 文件解析的问题,还是我看错了方式,有一种完全不同的方式来设置请求的 headers?

谢谢!

我不确定这是正确的方法,但最后我通过创建一个专用的可序列化 class 进行身份验证并向请求添加自定义 header 来管理。

        LanDB.NetworkServiceInterfaceClient client = new LanDB.NetworkServiceInterfaceClient();
        String token = client.getAuthToken("user", "name", "domain");
        Auth tokenAuth = new Auth(token);
        LanDB.DeviceInfo selectedPLCInfo = new LanDB.DeviceInfo();

        // Add a SOAP autentication Header (Header property in the envelope) to the outgoing request.
        using (new OperationContextScope(client.InnerChannel))
        {
            MessageHeader aMessageHeader = MessageHeader.CreateHeader("Auth", "", tokenAuth);
            OperationContext.Current.OutgoingMessageHeaders.Add(aMessageHeader);
            selectedPLCInfo = client.getDeviceInfo("plcHostname");
        }

随着class成为

[DataContract]
public class Auth
{

    [DataMember]
    string token;
    public Auth(string value)
    {
        token = value;
    }
}

这样 XML 请求就可以正确构建和发送了。

此外,如果我将服务添加为 Web 服务而不是服务引用,则需要 none。在那种情况下,我在客户端中得到一个 object,我可以使用正确的令牌设置 (AuthValue),并且客户端代码会处理所有事情。去图吧!