自訂訊息篩選條件

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

Aa717046.note(zh-tw,VS.100).gif注意:
此範例的安裝程序與建置指示位於本主題的結尾。

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

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

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

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

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),然後在每個通道傳送單一訊息,但是每個通道使用不同的端點位址。 因此,來自用戶端的傳出訊息會具有不同的 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" />
Aa717046.Important(zh-tw,VS.100).gif 注意:
這些範例可能已安裝在您的電腦上。 請先檢查下列 (預設) 目錄,然後再繼續。

<InstallDrive>:\WF_WCF_Samples

如果此目錄不存在,請移至用於 .NET Framework 4 的 Windows Communication Foundation (WCF) 與 Windows Workflow Foundation (WF) 範例 (英文),以下載所有 Windows Communication Foundation (WCF) 和 WF 範例。 此範例位於下列目錄。

<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\MessageFilter

若要安裝、建立及執行範例

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

  2. 若要在單一電腦組態中執行範例,請遵循Running the Windows Communication Foundation Samples中的指示。

  3. 若要在跨電腦的組態中執行範例,請遵循Running the Windows Communication Foundation Samples的指示,並且變更在 Client.cs 中的下列程式行。

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

    以伺服器名稱取代 localhost。

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