C# - Передача информации заголовка клиенту SOAP веб-сервиса - PullRequest
0 голосов
/ 09 июля 2020

Я добавил веб-сервис SOAP в качестве ссылки на сервис в проекте C# в Visual Studio, но либо я делаю что-то не так, либо он, похоже, не анализируется должным образом. WSDL явно предоставляет заголовок для передачи токена аутентификации (который я могу получить из другого метода), и на этот заголовок есть ссылка в методе, который мне нужно использовать (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 или я неправильно смотрю на него и есть совершенно другой способ установить заголовки в запросах?

Спасибо!

1 Ответ

1 голос
/ 10 июля 2020

Я не уверен, что это правильный способ сделать это, но в конце концов мне удалось создать специальный сериализуемый класс для аутентификации и добавить настраиваемый заголовок к запросу.

        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");
        }

С класс

[DataContract]
public class Auth
{

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

Таким образом, запрос XML будет правильно построен и отправлен.

Кроме того, ничего из этого не требуется, если я добавляю службу как веб-службу вместо Справка по обслуживанию. В этом случае я получаю в клиенте объект, который я могу установить (AuthValue) с правильным токеном, и клиентский код обрабатывает все. Go цифра!

...