共用方式為


自訂訊息篩選條件

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

注意

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

當通道上的第一個訊息抵達伺服器時,伺服器必須判定哪一個與該 URI 關聯的端點 (如果有的話) 應該要接收訊息。 這個程序會由附加至 MessageFilterEndpointDispatcher 物件控制。

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

根據預設,端點的 AddressFilter 會比對定址位址為符合服務端點之 EndpointAddress 的任何訊息。 根據預設,端點的 ContractFilter 會檢查傳入訊息的動作,並比對包含對應至服務端點合約作業之其中一個動作的任何訊息 (只考慮 IsInitiating=true 動作)。 因此,根據預設,只有在訊息的 To 標頭為端點的 EndpointAddress,而且訊息的動作符合其中一個端點作業動作時,端點的篩選條件才會相符。

這些篩選條件可以使用行為加以變更。 在此範例中,服務會建立可取代 IEndpointBehavior 上之 AddressFilterContractFilterEndpointDispatcher

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)),然後在每個通道傳送單一訊息,但是每個通道使用不同的端點位址。 因此,來自用戶端的傳出訊息會具有不同的 To 目的地,而伺服器會個別回應,如用戶端輸出所示:

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");