Подтвердить что ты не робот

Перехватывать SOAP-сообщения от и до веб-службы на клиенте

У меня есть клиент, который взаимодействует с веб-службой. Класс, с которым я общаюсь, является классом С#, который создается через wsdl.exe. Теперь я хочу регистрировать все входящие и исходящие сообщения.

Что я сделал до сих пор, так это написать класс, который наследуется от автоматически созданного класса С#, и я переопределил метод GetReaderForMessage. Таким образом, я могу получить доступ к входящему сообщению более или менее следующим образом:

protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize)
{
    System.Xml.XmlReader aReader = base.GetReaderForMessage(message, bufferSize);
    System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
    doc.Load(aReader);
    string content = doc.InnerXml.ToString();
    System.Xml.XmlReader aReader2 = System.Xml.XmlReader.Create(new System.IO.StringReader(content));

    return aReader2;
}

Очевидно, я не очень доволен этим решением, потому что в основном я создаю два xml-читателя. Один для чтения содержимого сообщения SOAP и один для возврата к вызывающему методу. Кроме того, я не могу сделать то же самое с методом GetWriterForMessage.

Но может быть, я просто делаю слишком трудные для начала. Возможно ли, например, напрямую прочитать содержимое объекта SoapClientMessage? Я прочитал несколько статей, в которых говорится, что я должен использовать SoapExtensions здесь, но из того, что я могу понять, это будет работать, только если "клиент", который я создаю, сам является веб-сервисом, который в этом случае не является.

Любые предложения?

4b9b3361

Ответ 1

Я бы предложил изучить использование расширения SOAP, которое, на мой взгляд, идеально подходит для этого сценария. Вот несколько ссылок, описывающих процесс.

http://msdn.microsoft.com/en-us/magazine/cc164007.aspx

https://ebay.custhelp.com/cgi-bin/ebay.cfg/php/enduser/std_adp.php?p_faqid=350

http://www.codeproject.com/KB/webservices/efficientsoapextension.aspx

Ответ 2

Чтобы использовать это решение, вам необходимо использовать ссылку "Добавить службу", а не "Добавить веб-ссылку", ее можно использовать, если услугой является ASMX или WCF. (Для использования этой функции вам необходимо использовать .NET Framework 3.X)

Эта статья поможет вам добавить ссылку на службу в ваш проект С#.

Чтобы перехватить и XML-запросы запроса и ответа, выполните следующие два класса:

public class InspectorBehavior : IEndpointBehavior
{
    public string LastRequestXML { 
        get
        {
            return myMessageInspector.LastRequestXML;
        }
    }

    public string LastResponseXML { 
        get
        {
            return myMessageInspector.LastResponseXML;
        }
    }


    private MyMessageInspector myMessageInspector = new MyMessageInspector();
    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {

    }

    public void Validate(ServiceEndpoint endpoint)
    {

    }


    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(myMessageInspector );
    }
}





public class MyMessageInspector : IClientMessageInspector
{
    public string LastRequestXML { get; private set; }
    public string LastResponseXML { get; private set; }
    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
    {
        LastResponseXML = reply.ToString();
    }

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
    {
        LastRequestXML = request.ToString();
        return request;
    }
}

Затем измените код вызова на:

MyTestServiceSoapClient client = new MyTestServiceSoapClient();
var requestInterceptor = new InspectorBehavior();
client.Endpoint.Behaviors.Add(requestInterceptor );
client.DoSomething("param1", "param2", "param3");
string requestXML = requestInterceptor.LastRequestXML;
string responseXML = requestInterceptor.LastResponseXML;

**** **** EDIT Это не связано с технологией serveride, вы можете использовать ее с WCF, ASMX, PHP,... веб-сервисами, которые я тестировал на: http://www.w3schools.com/webservices/tempconvert.asmx

И получили следующие XML:

requestXML =

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/CelsiusToFahrenheit</Action>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <CelsiusToFahrenheit xmlns="http://tempuri.org/">
      <Celsius>50</Celsius>
    </CelsiusToFahrenheit>
  </s:Body>
</s:Envelope>

responseXML =

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
  <soap:Body>
    <CelsiusToFahrenheitResponse xmlns="http://tempuri.org/">
      <CelsiusToFahrenheitResult>122</CelsiusToFahrenheitResult>
    </CelsiusToFahrenheitResponse>
  </soap:Body>
</soap:Envelope>

**** ИЗМЕНИТЬ 2 ****

"Добавить веб-справочник" не является специализированным для ASMX и не является клиентской технологией ASMX, а "Добавить ссылку на службу" - это не клиентская технология WCF, вы можете использовать оба варианта, чтобы добавить ссылку на ASMX, WCF, Разработанный JSP или разработанный PHP веб-сервис, вам необходимо, чтобы ваше приложение использовало .Net framework 3.5 для использования "Добавить ссылку на службу".

В этой статье упоминается:

При использовании диалогового окна Добавить веб-ссылку в Visual Studio клиент прокси генерируется с использованием информации WSDL и добавляется к визуальному Студийный проект. Обычно это используется для служб ASMX, но вы можете также используйте диалоговое окно "Добавить веб-ссылку", чтобы создать клиентский прокси для Услуги WCF. Однако вам нужно вручную ввести URL-адрес службы и созданный прокси использует сериализацию XML, которая является единственной поддерживается тип сериализации. Создание клиентских прокси для WCF услуг, поддерживающих сериализатор данных, вы можете использовать Svcutil.exe или используйте функцию добавления ссылки на службу Средства разработки Visual Studio для .NET Framework 3.x.