次の方法で共有


メッセージ フィルター

コンテンツ ベースのルーティングを実装する場合、ルーティング サービスは、アドレス、エンドポイント名、特定の XPath ステートメントなど、メッセージの特定のセクションを確認する MessageFilter 実装を使用します。 .NET Framework 4.6.1 で提供されるメッセージ フィルターの中にニーズを満たすものがない場合は、MessageFilter 基底クラスの新しい実装を作成することで、カスタム フィルターを作成できます。

ルーティング サービスを構成する場合、MessageFilter の型と、メッセージ内の検索に使用する特定の文字列値など、フィルターの作成に必要なサポート データを記述するフィルター要素 (FilterElement オブジェクト) を定義する必要があります。 フィルター要素を作成しても、個々のメッセージ フィルターが定義されるだけです。フィルターを使用してメッセージを評価およびルーティングするには、フィルター テーブル (FilterTableEntryCollection) を定義する必要もあります。

フィルター テーブル内の各エントリは、特定のフィルター要素を参照し、メッセージがフィルターに一致した場合にメッセージのルーティング先となるクライアント エンドポイントを指定します。 フィルター テーブルのエントリでは、バックアップ エンドポイントのコレクション (BackupEndpointCollection) を指定することもできます。このコレクションは、プライマリ エンドポイントへの送信時に転送エラーが発生した場合に、メッセージの転送先となるエンドポイントのリストを定義します。 それらのエンドポイントのいずれかで転送が成功するまで、指定された順番でバックアップ エンドポイントへの転送が試行されます。

メッセージ フィルター

ルーティング サービスが使用するメッセージ フィルターは、メッセージの送信先の名前、SOAP アクション、メッセージの送信先のアドレスまたはアドレス プレフィックスの評価など、一般的なメッセージ選択機能を提供します。 フィルターに AND 条件を付けて、メッセージが両方のフィルターに一致した場合は、特定のエンドポイントにのみルーティングされるように指定することもできます。 また、MessageFilter の独自の実装を作成することで、カスタム フィルターを作成することもできます。

次の表に、ルーティング サービスが使用する FilterType、そのメッセージ フィルターを実装するクラス、および必須の FilterData パラメーターを示します。

フィルターの種類 [説明] フィルター データの意味 フィルターの例
操作 ActionMessageFilter クラスを使用して、特定のアクションを含むメッセージを照合します。 フィルター処理するアクション。 <filter name="action1" filterType="Action" filterData="http://namespace/contract/operation" />
EndpointAddress EndpointAddressMessageFilter クラスを IncludeHostNameInComparison == true と組み合わせて使用して、特定のアドレスを含むメッセージを照合します。 フィルター処理するアドレス (To ヘッダー)。 <filter name="address1" filterType="EndpointAddress" filterData="http://host/vdir/s.svc/b" />
EndpointAddressPrefix PrefixEndpointAddressMessageFilter クラスを IncludeHostNameInComparison == true と組み合わせて使用して、特定のアドレス プレフィックスを含むメッセージを照合します。 最長プレフィックス一致を使用してフィルター処理するアドレス。 <filter name="prefix1" filterType="EndpointAddressPrefix" filterData="http://host/" />
And 常に両方の条件を評価してから結果を返す StrictAndMessageFilter クラスを使用します。 filterData は使用されません。代わりに、filter1 および filter2 には、対応するメッセージ フィルターの名前が (同じくテーブル内に) あるので、これらを AND で連結します。 <filter name="and1" filterType="And" filter1="address1" filter2="action1" />
Custom MessageFilter クラスを拡張し、文字列を受け取るコンストラクターを持つユーザー定義の型。 customType 属性は、作成するクラスの完全修飾型名で、filterData は、フィルターの作成時にコンストラクターに渡す文字列です。 <filter name="custom1" filterType="Custom" customType="CustomAssembly.CustomMsgFilter, CustomAssembly" filterData="Custom Data" />
EndpointName EndpointNameMessageFilter クラスを使用して、メッセージを受信したサービス エンドポイントの名前を基にメッセージを照合します。 サービス エンドポイントの名前 ("serviceEndpoint1" など)。 このサービス エンドポイントは、ルーティング サービスで公開されるいずれかのエンドポイントでなければなりません。 <filter name="stock1" filterType="Endpoint" filterData="SvcEndpoint" />
MatchAll MatchAllMessageFilter クラスを使用します。 このフィルターは、すべての着信メッセージを照合します。 filterData は使用されません。 このフィルターは、常にすべてのメッセージを照合します。 <filter name="matchAll1" filterType="MatchAll" />
XPath XPathMessageFilter クラスを使用して、メッセージ内の特定の XPath クエリを照合します。 メッセージの照合時に使用する XPath クエリ。 <filter name="XPath1" filterType="XPath" filterData="//ns:element" />

次の例では、XPath、EndpointName、および PrefixEndpointAddress メッセージ フィルターを使用するフィルター エントリを定義しています。 また、この例では、RoundRobinFilter1 エントリと RoundRobinFilter2 エントリに対するカスタム フィルターの使用方法も示しています。

<filters>  
     <filter name="XPathFilter" filterType="XPath"
             filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>  
     <filter name="EndpointNameFilter" filterType="EndpointName"
             filterData="calculatorEndpoint"/>  
     <filter name="PrefixAddressFilter" filterType="PrefixEndpointAddress"
             filterData="http://localhost/routingservice/router/rounding/"/>  
     <filter name="RoundRobinFilter1" filterType="Custom"
             customType="RoutingServiceFilters.RoundRobinMessageFilter,
             RoutingService" filterData="group1"/>  
     <filter name="RoundRobinFilter2" filterType="Custom"
             customType="RoutingServiceFilters.RoundRobinMessageFilter,
             RoutingService" filterData="group1"/>  
</filters>  

Note

単にフィルターを定義しただけでは、そのフィルターに対してメッセージが評価されるとは限りません。 フィルターをフィルター テーブルに追加する必要があります。テーブルに追加することで、ルーティング サービスが公開するサービス エンドポイントに関連付けられます。

名前空間テーブル

XPath フィルターを使用すると、XPath クエリを含むフィルター データは、名前空間を使用するため、非常に大きくなることがあります。 この問題を軽減するために、ルーティング サービスでは、名前空間テーブルを使用して、独自の名前空間プレフィックスを定義できるようにしています。

名前空間テーブルは、XPath で使用できる一般的な名前空間の名前空間プレフィックスを定義する NamespaceElement オブジェクトのコレクションです。 以下は、名前空間テーブルに格納されている既定の名前空間およびプレフィックスです。

Prefix 名前空間
s11 http://schemas.xmlsoap.org/soap/envelope
s12 http://www.w3.org/2003/05/soap-envelope
wsaAugust2004 http://schemas.xmlsoap.org/ws/2004/08/addressing
wsa10 http://www.w3.org/2005/08/addressing
sm http://schemas.microsoft.com/serviceModel/2004/05/xpathfunctions
tempuri http://tempuri.org
ser http://schemas.microsoft.com/2003/10/Serialization

XPath クエリに特定の名前空間を使用することがわかっている場合は、その名前空間を一意の名前空間プレフィックスと併せて名前空間テーブルに追加し、完全名前空間ではなく、プレフィックスを XPath クエリで使用できます。 次の例では、名前空間 "http://my.custom.namespace" に対して "custom" というプレフィックスを定義し、これを filterData 内の XPath クエリで使用しています。

<namespaceTable>  
     <add prefix="custom" namespace="http://my.custom.namespace/"/>  
</namespaceTable>  
<filters>  
     <filter name="XPathFilter" filterType="XPath" filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>  
</filters>  

フィルター テーブル

各フィルター要素では、メッセージに適用できる論理比較が定義されますが、フィルター テーブルでは、フィルター要素と送信先クライアント エンドポイントが関連付けられます。 フィルター テーブルは、フィルター、プライマリの送信先エンドポイント、および代替のバックアップ エンドポイントのリスト間の関連付けを定義する FilterTableEntryElement オブジェクトの名前付きコレクションです。 フィルター テーブル エントリでは、必要に応じて、各フィルター条件に優先度を指定することもできます。 次の例では、まず、2 つのフィルターを定義し、各フィルターを送信先エンドポイントに関連付けるフィルター テーブルを定義しています。

<routing>  
     <filters>  
       <filter name="AddAction" filterType="Action" filterData="Add" />  
       <filter name="SubtractAction" filterType="Action" filterData="Subtract" />  
     </filters>  
     <filterTables>  
       <table name="routingTable1">  
         <filters>  
           <add filterName="AddAction" endpointName="Addition" />  
           <add filterName="SubtractAction" endpointName="Subtraction" />  
         </filters>  
       </table>  
     </filterTables>
</routing>  

フィルター評価の優先度

既定では、フィルター テーブルのすべてのエントリが同時に評価され、評価対象のメッセージは、一致するフィルター エントリに関連付けられているエンドポイントにルーティングされます。 複数のフィルターが true に評価され、メッセージが一方向または双方向である場合は、メッセージが、一致するすべてのフィルターのエンドポイントにマルチキャストされます。 要求/応答メッセージは、クライアントに返すことができる応答が 1 つのみであるため、マルチキャストできません。

各フィルターに優先度レベルを指定することで、より複雑なルーティング ロジックを実装できます。ルーティング サービスは、優先度レベルが最も高いフィルターをすべて最初に評価します。 メッセージがこのレベルのフィルターに一致した場合、優先度がこれよりも低いフィルターは処理されません。 たとえば、一方向の受信メッセージは、最初に、優先度が 2 であるすべてのフィルターに対して評価されるとします。 この優先度レベルのどのフィルターにもメッセージが一致しなかった場合は、次に、優先度が 1 のフィルターと比較されます。 優先度 1 のフィルターのうち、2 つがメッセージに一致した場合、メッセージは、一方向のメッセージであるため、両方の送信先エンドポイントにルーティングされます。 優先度 1 のフィルターの中に一致するものが見つかったため、優先度が 0 のフィルターは評価されません。

Note

優先度が指定されていない場合は、既定の優先度の 0 が使用されます。

次の例では、フィルター テーブルを定義しています。このテーブルでは、テーブルで参照しているフィルターに優先度 2、1、および 0 を指定しています。

<filterTables>  
     <filterTable name="filterTable1">  
          <add filterName="XPathFilter" endpointName="roundingCalcEndpoint"
               priority="2"/>  
          <add filterName="EndpointNameFilter" endpointName="regularCalcEndpoint"
               priority="1"/>  
          <add filterName="PrefixAddressFilter" endpointName="roundingCalcEndpoint"
               priority="1"/>  
          <add filterName="MatchAllMessageFilter" endpointName="defaultCalcEndpoint"
               priority="0"/>  
     </filterTable>  
</filterTables>  

上記の例では、メッセージが XPathFilter に一致すると、roundingCalcEndpoint にルーティングされます。また、その他のフィルターはすべて、これよりも優先度が低いため、テーブル内の他のフィルターは評価されません。 ただし、メッセージが XPathFilter に一致しなかった場合は、次に優先度が低いすべてのフィルター、つまり、EndpointNameFilter と PrefixAddressFilter に対してメッセージが評価されます。

Note

可能な場合は、優先度の評価によってパフォーマンスが低下する可能性があるため、優先度を指定する代わりに、排他的なフィルターを使用してください。

バックアップ リスト

フィルター テーブルの各フィルターには、必要に応じて、バックアップ リストを指定できます。バックアップ リストは、エンドポイントの名前付きコレクション (BackupEndpointCollection) です。 このコレクションには、CommunicationException に指定されているプライマリ エンドポイントへの送信時に EndpointName が発生した場合に、メッセージの転送先となるエンドポイントの順序指定されたリストが保持されます。 次の例では、2 つのエンドポイントを保持している "backupServiceEndpoints" という名前のバックアップ リストを定義しています。

<filterTables>  
     <filterTable name="filterTable1">  
          <add filterName="MatchAllFilter1" endpointName="Destination" backupList="backupEndpointList"/>  
     </filterTable>  
</filterTables>  
<backupLists>  
     <backupList name="backupEndpointList">  
          <add endpointName="backupServiceQueue" />  
          <add endpointName="alternateServiceQueue" />  
     </backupList>  
</backupLists>  

上記の例では、プライマリ エンドポイント "Destination" への送信が失敗した場合、ルーティング サービスでは、シーケンス内の各エンドポイントへの送信が試行されます。まず、backupServiceQueue への送信が試行され、backupServiceQueue への送信が失敗した場合は、alternateServiceQueue への送信が試行されます。 すべてのバックアップ エンドポイントへの送信が失敗した場合は、エラーが返されます。