簡體   English   中英

攔截來自客戶端的Web服務的SOAP消息

[英]Intercept SOAP messages from and to a web service at the client

我有一個與Web服務通信的客戶端。 我與之通信的類是通過wsdl.exe生成的C#類。 我現在想記錄所有傳入和傳出的消息。

到目前為止我所做的是編寫一個繼承自動生成的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,但是從我能理解的情況來看,只有我創建的'客戶'本身就是一個Web服務,在這種情況下它不是。

有什么建議么?

您需要使用“添加服務引用”而不是“添加Web引用”功能來使用此解決方案,如果服務是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,... Web服務一起使用,我已經測試過: http//www.w3schools.com/ Web服務/ 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 ****

“添加Web引用”不是專用於ASMX而不是ASMX客戶端技術,而“添加服務引用”不是WCF客戶端技術,您可以使用它們來添加對ASMX,WCF,JSP開發的引用或PHP開發的Web服務,您需要您的應用程序使用.Net framework 3.5來使用“添加服務引用”。

本文提到:

在Visual Studio中使用“添加Web引用”對話框時,將使用WSDL信息生成客戶端代理,並將其添加到Visual Studio項目中。 這通常用於ASMX服務,但您也可以使用“添加Web引用”對話框為WCF服務創建客戶端代理。 但是,您需要手動鍵入服務URL,並且生成的代理使用XML序列化,這是唯一支持的序列化類型。 若要為支持數據協定序列化程序的WCF服務創建客戶端代理,可以使用Svcutil.exe工具或使用.NET Framework 3.x的Visual Studio開發工具的“添加服務引用”功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM