web-dev-qa-db-ja.com

インターセプトSOAPクライアントのWebサービスとの間のメッセージ

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

基本的に私は2つのxmlリーダーを作成しているため、明らかにこのソリューションに満足していません。 1つはSOAPメッセージの内容を読み取るためのもので、もう1つはメソッドの呼び出し元に戻るためのものです。さらに、GetWriterForMessageメソッドを使用して同じことを行うことはできません。

でも、最初は難しすぎることをしているだけかもしれません。たとえば、SoapClientMessageオブジェクトのコンテンツを直接読み取ることはできますか?ここでSoapExtensionsの使用を提案する記事をいくつか読んだことがありますが、理解できることから、作成している「クライアント」自体がWebサービスであり、この場合はそうではない場合にのみ機能します。

助言がありますか?

25
trabart

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=35

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

6
Garett

このソリューションを使用するには、「Web参照の追加」機能ではなく「サービス参照の追加」機能を使用する必要があります。サービスがASMXまたはWCFの場合に使用できます。 (この機能を使用するには、.NET Framework 3.Xを使用する必要があります)

この記事 は、C#プロジェクトにサービス参照を追加するのに役立ちます。

リクエストとレスポンスのXMLをインターセプトするには、次の2つのクラスを実装します。

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/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 ****

「Add Web Reference」はASMXに特化したものではなく、ASMXクライアント側のテクノロジーでもありません。「Add Service Reference」は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開発ツールのサービス参照の追加機能を使用できます。

54
Sawan