Перехват SOAP-сообщений от и до веб-службы на клиенте - PullRequest
23 голосов
/ 07 октября 2010

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

На данный момент я написал класс, который наследуется от автоматически сгенерированного класса C #, и я переопределил метод 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, но из того, что я могу понять, это сработало бы, только если создаваемый мною «клиент» сам по себе является веб-службой, а в данном случае - нет.

Есть предложения?

Ответы [ 2 ]

50 голосов
/ 08 декабря 2012

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

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

ДляПерехват и 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;

**** РЕДАКТИРОВАТЬ ****Это не связано с серверной технологией, вы можете использовать ее с веб-службами 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>

**** EDIT 2 ****

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

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

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

5 голосов
/ 07 октября 2010

Я бы предложил использовать расширение 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

...