共用方式為


自訂訊息篩選

MessageFilter 範例示範如何取代 Windows Communication Foundation (WCF) 用來將訊息分派至端點的訊息篩選。

備註

此範例的安裝程式和建置指示位於本主題結尾。

當通道上的第一個訊息到達伺服器時,伺服器必須判斷與該 URI 相關聯的端點應該接收訊息的哪個(如果有的話)。 此程式是由 MessageFilter 附加至 EndpointDispatcher的物件所控制。

服務的每個端點都有一個EndpointDispatcherEndpointDispatcher同時具有 AddressFilterContractFilter。 這兩個篩選條件的聯集是用於該端點的訊息篩選。

根據預設,AddressFilter 端點將匹配任何被尋址至符合服務端點的 EndpointAddress 位址的訊息。 根據預設,ContractFilter 端點會檢查傳入訊息的動作,並將傳入訊息與服務端點合約作業的一個動作相符(只會考慮IsInitiating=true動作)。 因此,根據預設,只有在訊息的 To 標頭是端點的 EndpointAddress,且訊息的動作符合其中一個端點操作的動作時,端點的篩選器才會匹配。

您可以使用行為來變更這些篩選。 在範例中,服務會建立IEndpointBehavior,以取代AddressFilter上的ContractFilterEndpointDispatcher

class FilteringEndpointBehavior : IEndpointBehavior
{
    //...
}

定義兩個地址篩選:

// Matches any message whose To address contains the letter 'e'
class MatchEAddressFilter : MessageFilter { }
// Matches any message whose To address does not contain the letter 'e'
class MatchNoEAddressFilter : MessageFilter { }

FilteringEndpointBehavior可設定 ,並允許兩個不同的變化。

public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement { }

變化 1 只會比對包含 'e' 的位址(但具有任何動作),而變化 2 只比對缺少 'e' 的位址:

if (Variation == 1)
    return new FilteringEndpointBehavior(
        new MatchEAddressFilter(), new MatchAllMessageFilter());
else
    return new FilteringEndpointBehavior(
        new MatchNoEAddressFilter(), new MatchAllMessageFilter());

在組態檔中,服務會註冊新的行為:

<extensions>
    <behaviorExtensions>
        <add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
    </behaviorExtensions>
</extensions>

然後服務會為每個版本建立endpointBehavior組態。

<endpointBehaviors>
    <behavior name="endpoint1">
        <filteringEndpointBehavior variation="1" />
    </behavior>
    <behavior name="endpoint2">
        <filteringEndpointBehavior variation="2" />
    </behavior>
</endpointBehaviors>

最後,服務的端點會參考其中 behaviorConfigurations一個 :

<endpoint address=""
        bindingConfiguration="ws"
        listenUri=""
        binding="wsHttpBinding"
        contract="Microsoft.ServiceModel.Samples.IHello"
        behaviorConfiguration="endpoint2" />

用戶端應用程式的實作很簡單;它會為服務的 URI 建立兩個通道(將該值當做第二個 (via) 參數 CreateChannel(EndpointAddress) 傳入,並在每個通道上傳送單一訊息,但會針對每個通道使用不同的端點位址。 因此,客戶端發送的訊息具有不同的收件人,伺服器會據此回應,如客戶端的輸出所示:

Sending message to urn:e...
Exception: The message with To 'urn:e' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

Sending message to urn:a...
Hello

切換伺服器組態檔中的變異會導致過濾器被交換,用戶端將會看到相反的行為(訊息傳送到 urn:e 成功,而傳送到 urn:a 則失敗)。

<endpoint address=""
          bindingConfiguration="ws"
          listenUri=""
          binding="wsHttpBinding"
          contract="Microsoft.ServiceModel.Samples.IHello"
          behaviorConfiguration="endpoint1" />

要設定、建置和執行範例,請執行以下步驟:

  1. 若要建置解決方案,請遵循 建置 Windows Communication Foundation 範例中的指示。

  2. 若要在單一計算機設定中執行範例,請遵循 執行 Windows Communication Foundation 範例中的指示。

  3. 若要在跨計算機組態中執行範例,請遵循執行 Windows Communication Foundation 範例 中的指示,並在 Client.cs中變更下列這一行。

    Uri serviceVia = new Uri("http://localhost/ServiceModelSamples/service.svc");
    

    以伺服器名稱取代localhost。

    Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");