Filtro messaggi personalizzato

Questo esempio dimostra come sostituire i filtri messaggi che Windows Communication Foundation (WCF) utilizza per distribuire messaggi agli endpoint.

Nota

La procedura di installazione e le istruzioni di generazione per questo esempio si trovano alla fine di questo argomento.

Quando il primo messaggio su un canale arriva al server, il server deve determinare quale degli endpoint associati all'URI (se presenti) deve ricevere il messaggio. Questo processo viene controllato dagli oggetti MessageFilter allegati a EndpointDispatcher.

Ogni endpoint di un servizio ha un solo EndpointDispatcher. La classe EndpointDispatcher è dotata delle proprietà AddressFilter e ContractFilter. L'unione di questi due filtri è il filtro messaggi utilizzato per quell'endpoint.

Per impostazione predefinita, la proprietà AddressFilter per un endpoint corrisponde a qualsiasi messaggio indirizzato a un indirizzo che corrisponde alla classe EndpointAddress dell'endpoint del servizio. Per impostazione predefinita, la proprietà ContractFilter per un endpoint esamina l'azione del messaggio in ingresso e corrisponde a qualsiasi messaggio con un'azione che corrisponde a una delle azioni delle operazioni del contratto dell'endpoint del servizio (vengono considerate solo le azioni IsInitiating=true). Di conseguenza, per impostazione predefinita il filtro per un endpoint corrisponde solo se l'intestazione di destinazione del messaggio rappresenta la classe EndpointAddress dell'endpoint e l'azione del messaggio corrisponde a una delle azioni dell'operazione dell'endpoint.

Questi filtri possono essere modificati utilizzando un comportamento. Nell'esempio, il servizio crea un'interfaccia IEndpointBehavior che sostituisce le proprietà AddressFilter e ContractFilter nella classe EndpointDispatcher:

class FilteringEndpointBehavior : IEndpointBehavior …

Vengono definiti due filtri per l'indirizzo:

// 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 è reso configurabile e consente due variazioni diverse.

public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement

La variazione 1 corrisponde solo agli indirizzi che contengono una 'e' (ma che sono dotati di qualsiasi azione), mentre la variazione 2 corrisponde solo agli indirizzi a cui manca una 'e':

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

Il servizio registra il nuovo comportamento nel file di configurazione:

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

Il servizio quindi crea le configurazioni endpointBehavior per ogni variazione:

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

L'endpoint del servizio infine fa riferimento a uno degli elementi behaviorConfigurations:

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

L'implementazione dell'applicazione client è semplice: crea due canali sull'URI del servizio passando quel valore come il secondo parametro (via) su CreateChannel e invia un solo messaggio su ogni canale, utilizzando però indirizzi endpoint diversi per ognuno. Di conseguenza, i messaggi in uscita dal client hanno designazioni di destinazione diverse e il server risponde appropriatamente, come dimostrato dall'output del client:

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

Scambiando la variazione nel file di configurazione del server il filtro viene scambiato e il client visualizza il comportamento contrario (il messaggio a urn:e viene completato, mentre il messaggio a urn:a ha esito negativo).

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

Per impostare, compilare ed eseguire l'esempio

  1. Per generare la soluzione, seguire le istruzioni in Generazione degli esempi Windows Communication Foundation.

  2. Per eseguire l'esempio su un solo computer, seguire le istruzioni in Esecuzione degli esempi di Windows Communication Foundation.

  3. Per eseguire l'esempio tra computer diversi, seguire le istruzioni in Esecuzione degli esempi di Windows Communication Foundation e modificare la seguente riga in Client.cs.

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

    Sostituire localhost con il nome del server.

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

Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.