Condividi tramite


Filtro messaggi personalizzato

L'esempio MessageFilter illustra come sostituire i filtri messaggi usati da Windows Communication Foundation (WCF) per inviare messaggi agli endpoint.

Nota

La procedura di installazione e le istruzioni di compilazione 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(EndpointAddress) 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

La commutazione della variazione nel file di configurazione del server determina lo scambio del filtro e la visualizzazione da parte del client del comportamento contrario (il messaggio a urn:e ha esito positivo, 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 compilare la soluzione, seguire le istruzioni in Compilazione degli esempi di Windows Communication Foundation.

  2. Per eseguire l'esempio in una configurazione a computer singolo, 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 cambiare la riga seguente in Client.cs.

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

    Sostituire localhost con il nome del server.

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