SOAP 拡張機能を使用した SOAP メッセージの変更

このトピックの対象は、レガシ テクノロジに特定されています。XML Web サービスと XML Web サービス クライアントは以下を使用して作成してください。 Windows Communication Foundation.

SOAP 拡張機能を使用すると、開発者は Web サービスや Web サービス クライアントの間で送受信される SOAP メッセージを変更して、Web サービスの機能を拡張できます。たとえば、既存の Web サービスで実行する暗号化方式や圧縮アルゴリズムを実装できます。

SOAP 拡張機能のしくみを理解するには、まず、Web サービスの有効期間を理解しておくとわかりやすくなります。詳細については、「XML Web サービスの有効期間の構造」を参照してください。

クライアントからの Web サービス呼び出しの主要フェーズを次の図に示します。

XML Web サービスの有効期間

上の図からわかるように、.NET Framework は各フェーズで、Web サービス コンピューターと Web サービス クライアント コンピューターの両方で XML をシリアル化および逆シリアル化します。SOAP 拡張機能をインフラストラクチャに挿入して、シリアル化および逆シリアル化の各フェーズの前後に SOAP メッセージの検査や変更を行うことができます。たとえば、SOAP 拡張機能の暗号化では、.NET Framework がクライアントの引数をシリアル化した後に SOAP メッセージの XML 部分を暗号化し、その後 .NET Framework が SOAP メッセージを逆シリアル化する前に Web サーバーで SOAP メッセージを復号化します。SOAP 拡張機能が SOAP メッセージの検査や変更を行うこれらのフェーズは、SoapMessageStage 列挙体で定義されます。この場合、SOAP 拡張機能は AfterSerialize ステージで暗号化を行い、BeforeDeserialize ステージで復号化を行います。

通常、SOAP 拡張機能で SOAP メッセージの内容を変更する場合、クライアントとサーバーの両方で変更を行う必要があります。つまり、SOAP 拡張機能をクライアントで実行して SOAP メッセージを暗号化した場合は、対応する SOAP 拡張機能がサーバー上で SOAP メッセージを復号化する必要があります。SOAP メッセージを復号化しない場合、ASP.NET インフラストラクチャでは SOAP メッセージをオブジェクトに逆シリアル化できません。

もちろん、SOAP メッセージを記録するだけの SOAP 拡張機能など、SOAP メッセージを変更しない SOAP 拡張機能は、クライアントまたはサーバーだけで実行できます。この場合、受信側は、SOAP 拡張機能を実行しない場合と同じ SOAP メッセージを受信し、ASP.NET インフラストラクチャで SOAP メッセージを逆シリアル化できます。また、SOAP 拡張機能で、逆シリアル化が不可能になるような形の変更が行われていなければ、クライアントとサーバーの両方で SOAP 拡張機能を実行する必要はありません。

SOAPExtension クラスの拡張

SOAP 拡張機能を実装するには、SoapExtension クラスの派生クラスを作成します。SOAPExtension クラスには、実装が必要なメソッドが 3 つあります。

これらのメソッドの実装手順の詳細については、「チュートリアル : SOAP 拡張機能を使用した SOAP メッセージの変更」を参照してください。

ChainStream メソッドは Stream オブジェクトを受け取り、Stream オブジェクトを返します。各 SoapMessageStage の間に SOAP 拡張機能を実行して SOAP メッセージを変更するとき、SOAP 拡張機能は ChainStream に渡される Stream から読み込み、ChainStream から返される Stream に書き込む必要があります。したがって、ChainStream メソッド内で両方の Stream 参照をメンバー変数に割り当てることが重要です。

SoapExtension の派生クラスは GetInitializer メソッドおよび Initialize メソッドを使用し、データが適用される Web サービスまたは Web サービス メソッドに基づいて内部データを初期化します。たとえば、Web サービス メソッド間で送受信される SOAP メッセージのログを記録する SOAP 拡張機能では、SOAP 拡張機能を実行する Web サービスまたは Web サービス メソッドの名前に基づいて、ログ情報を保存するファイル名を初期化することがあります。

次に示すように、Web サービス インフラストラクチャが GetInitializer メソッドを呼び出すタイミングと、このメソッドに渡されるパラメーターは、SOAP 拡張機能の構成方法によって異なります。

  • 属性を使って SOAP 拡張機能が構成されている場合は、最初に Web サービス method がアクセスされたときに、Web サービス インフラストラクチャが GetInitializer を呼び出します。

  • 構成ファイルで SOAP 拡張機能が構成されている場合は、最初に Web サービス全体がアクセスされたときのみ、Web サービス インフラストラクチャが GetInitializer を呼び出します。

Web サービス インフラストラクチャは、GetInitializer メソッドが返すオブジェクトをキャッシュします。その後、SOAP 拡張機能が Web サービスまたは Web サービス メソッドで実行されるたびに、インフラストラクチャは初期化オブジェクトを Initialize メソッドに渡します。

標準の SOAP 処理を超える実際の拡張処理は、ProcessMessage メソッドによって実行されます。Web サービス インフラストラクチャが ProcessMessage を呼び出すたびに、特定のステージの SOAP メッセージに関する情報を含む SoapMessage の派生クラスのインスタンスが引数として渡されます。SOAP 拡張機能を Web サービスで実行する場合は SoapServerMessage オブジェクト、Web サービス クライアントで実行する場合は SoapClientMessage オブジェクトが渡されます。

SOAP 拡張機能と例外

SOAP 拡張機能は例外自体をスローすることはできません。ただし、 ProcessMessage メソッドで渡される SoapMessage オブジェクトの Exception プロパティに例外情報を追加することはできます。

また、SOAP 拡張機能がインストールされたアプリケーション内のすべての例外を同じ機能を使用してキャッチすることにより、アプリケーション全体の例外ハンドラーとしても機能し、返された SOAP エラーの変更など、いくつかの動作を実行できます。

SOAP 拡張機能メソッドが呼び出される順序

これまで、SOAP 拡張機能がオーバーライドするメソッドについて説明してきました。ここでは、Web サービス メソッドの呼び出し中に Web サービス インフラストラクチャが SOAP 拡張機能メソッドを呼び出すタイミングについて説明します。次の手順では、SOAP 拡張機能をクライアントとサーバーの両方で実行していることを前提としています。両方で実行していない場合、.NET Framework はそれぞれで実行する SOAP 拡張機能に関連する手順を無視します。

クライアント側での要求メッセージの準備

  1. クライアントがプロキシ クラスに対してメソッドを呼び出します。

  2. SOAP 拡張機能の新しいインスタンスがクライアントで作成されます。

  3. この SOAP 拡張機能をクライアントの Web サービスで初めて実行した場合は、クライアントで実行している SOAP 拡張機能で GetInitializer メソッドが呼び出されます。

  4. Initialize メソッドが呼び出されます。

  5. ChainStream メソッドが呼び出されます。

  6. SoapMessageStageBeforeSerialize に設定された ProcessMessage メソッドが呼び出されます。

  7. クライアント コンピューターの ASP.NET が、Web サービス メソッドの引数を XML にシリアル化します。

  8. SoapMessageStageAfterSerialize に設定された ProcessMessage メソッドが呼び出されます。

  9. クライアント コンピューターの ASP.NET が、Web サービスをホストする Web サーバーにネットワーク経由で SOAP メッセージを送信します。

サーバー側での要求メッセージの受信と応答の準備

  1. Web サーバーの ASP.NET が SOAP メッセージを受信します。

  2. SOAP 拡張機能の新しいインスタンスが Web サーバーで作成されます。

  3. Web サーバー側の Web サービスでこの SOAP 拡張機能を初めて実行した場合は、サーバーで実行している SOAP 拡張機能で GetInitializer メソッドが呼び出されます。

  4. Initialize メソッドが呼び出されます。

  5. ChainStream メソッドが呼び出されます。

  6. SoapMessageStageBeforeDeserialize に設定された ProcessMessage メソッドが呼び出されます。

  7. ASP.NET が XML 内の引数を逆シリアル化します。

  8. SoapMessageStageAfterDeserialize に設定された ProcessMessage メソッドが呼び出されます。

  9. ASP.NET が、Web サービスを実装するクラスの新しいインスタンスを作成し、逆シリアル化した引数で渡して、Web サービス メソッドを呼び出します。このオブジェクトは、Web サーバーと同じコンピューター上に配置されます。

  10. Web サービス メソッドはそのコードを実行し、最終的に戻り値と出力パラメーターを設定します。

  11. SoapMessageStageBeforeSerialize に設定された ProcessMessage メソッドが呼び出されます。

  12. Web サーバーの ASP.NET が、戻り値と出力パラメーターを XML にシリアル化します。

  13. SoapMessageStageAfterSerialize に設定された ProcessMessage メソッドが呼び出されます。

  14. ASP.NET が、Web サービス クライアントにネットワーク経由で SOAP 応答メッセージを送信します。

クライアント側での応答メッセージの受信

  1. クライアント コンピューターの ASP.NET が SOAP メッセージを受信します。

  2. SoapMessageStageBeforeDeserialize に設定された ProcessMessage メソッドが呼び出されます。

  3. ASP.NET が XML を戻り値と出力パラメーターに逆シリアル化します。

  4. SoapMessageStageAfterDeserialize に設定された ProcessMessage メソッドが呼び出されます。

  5. ASP.NET が、戻り値と出力パラメーターをプロキシ クラスのインスタンスに渡します。

  6. クライアントが戻り値と出力パラメーターを受け取ります。

SOAP 拡張機能の実装

クライアントまたはサーバー アプリケーションで SOAP 拡張機能を実行するには、2 つの方法があります。1 つは、拡張機能を実行するようにアプリケーションを構成する方法です。すべての Web サービス (特に vroot) ですべての Web メソッドに対して実行するように SOAP 拡張機能を構成するには、Web.config ファイルの <soapExtensionTypes> 要素 セクションを編集します。次のコードは、type 属性の値を 1 行で指定し、拡張機能の完全修飾名と、署名されたアセンブリのバージョン、カルチャ、公開キー トークンを含める必要があることを示しています。

<configuration>
 <system.web>
    <webServices>
      <soapExtensionTypes>
        <add type="Contoso.MySoapExtension, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
priority="1" group="0"/>
        </soapExtensionTypes>
    </webServices>
  </system.web>
</configuration>

もう 1 つは、Web サービス メソッドに適用されるカスタム属性を作成する方法です。カスタム属性を作成するには、SoapExtensionAttribute の派生クラスを作成します。カスタム属性の作成の詳細については、「方法 : SOAP 拡張機能を実装する」を参照してください。カスタム属性の作成に関するその他の情報については、「カスタム属性の作成」を参照してください。

esw638yk.note(ja-jp,VS.100).gif注 :
SOAP 拡張機能の実装時、拡張機能でのデータ ストリームの読み込みに XmlTextReader を使用すると、サービス拒否 (DOS) 攻撃が試みられる可能性があります。こうした攻撃を防ぐ方法の 1 つとして、ProhibitDtd プロパティを true に設定します。

優先順位と優先順位グループ

属性または構成を使用して、SOAP 拡張機能に優先順位を割り当てることができます。優先順位は、XML Web サービス メソッドで実行する SOAP 拡張機能が複数構成されている場合に、相対的な実行順序を決定するのに役立ちます。優先順位が高い SOAP 拡張機能ほど、ネットワーク経由で送受信される SOAP メッセージに対して早く実行されます。SOAP 拡張機能は 3 つの優先順位グループのいずれかに属しています。各グループ内では、priority プロパティによって各メンバーが識別されます。priority プロパティの値が小さいほど相対的な優先順位が高くなります。最も優先順位が高いのは 0 です。

SOAP 拡張機能の相対的な優先順位グループには、属性を使用して構成された SOAP 拡張機能、構成ファイルで group0 を設定した SOAP 拡張機能、1 を設定した SOAP 拡張機能の 3 つがあります。これらの優先順位は次のようになります。

  • 最も優先順位が高いグループは、構成ファイルで group0 に設定して構成された SOAP 拡張機能です。

  • 次に優先順位が高いグループは、属性を使用して構成された SOAP 拡張機能です。

  • 最も優先順位が低いグループは、構成ファイルで group1 に設定して構成された SOAP 拡張機能です。

相対的な優先順位グループを 0、優先順位を 1 にして Logger.LoggerExtension SOAP 拡張機能を実行するように指定した構成ファイルのコード例を次に示します。

<configuration>
 <system.web>
   <webServices>
     <soapExtensionTypes>
      <add type="Logger.LoggerExtension,logger"
           priority="1"
           group="0" />
     </soapExtensionTypes>
    </webServices>
 </system.web>
</configuration>

参照

処理手順

方法 : SOAP 拡張機能を実装する

リファレンス

SoapExtension
SoapExtensionAttribute
SoapMessageStage
LogicalMethodInfo

概念

SOAP 拡張機能を使用した SOAP メッセージの変更
XML Web サービスの有効期間の構造
XML Web サービス クライアントの作成

その他のリソース

Configuring Applications
ASP.NET を使用した XML Web サービス