Custom Message Filter
L’exemple MessageFilter montre comment remplacer les filtres de messages que Windows Communication Foundation (WCF) utilise pour distribuer des messages aux points de terminaison.
Notes
La procédure d'installation ainsi que les instructions de génération relatives à cet exemple figurent à la fin de cette rubrique.
Lorsque le premier message sur un canal arrive au niveau du serveur, ce dernier doit déterminer le point de terminaison (le cas échéant) associé à cet URI qui doit recevoir le message. Ce processus est contrôlé par les objets MessageFilter joints à EndpointDispatcher.
Chaque point de terminaison d'un service a un EndpointDispatcher unique. EndpointDispatcher possède à la fois AddressFilter et ContractFilter. L'association de ces deux filtres forme le filtre de messages utilisé pour ce point de terminaison.
Par défaut, le AddressFilter d'un point de terminaison correspond aux messages envoyés à une adresse qui correspond au EndpointAddress du point de terminaison de service. Par défaut, le ContractFilter d’un point de terminaison inspecte l’action du message entrant et correspond aux messages avec une action qui correspond à l’une des actions des opérations du contrat de point de terminaison de service (seules les actions IsInitiating
=true
sont prises en compte). Par défaut, le filtre d'un point de terminaison correspond donc uniquement si l'en-tête To du message est le EndpointAddress du point de terminaison et que l'action du message correspond à l'une des actions de l'opération de point de terminaison.
Ces filtres peuvent être modifiés à l'aide d'un comportement. Dans l'exemple, le service crée un IEndpointBehavior qui remplace AddressFilter et ContractFilter sur EndpointDispatcher:
class FilteringEndpointBehavior : IEndpointBehavior
{
//...
}
Deux filtres d'adresse sont définis :
// 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
est rendu configurable et accepte deux variantes différentes.
public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement { }
La variante 1 correspond uniquement aux adresses qui contiennent un 'e' (mais qui comportent des actions), tandis que la variante 2 correspond uniquement aux adresses sans 'e' :
if (Variation == 1)
return new FilteringEndpointBehavior(
new MatchEAddressFilter(), new MatchAllMessageFilter());
else
return new FilteringEndpointBehavior(
new MatchNoEAddressFilter(), new MatchAllMessageFilter());
Dans le fichier de configuration, le service enregistre le nouveau comportement :
<extensions>
<behaviorExtensions>
<add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
</behaviorExtensions>
</extensions>
Il crée ensuite des configurations endpointBehavior
pour chaque variante :
<endpointBehaviors>
<behavior name="endpoint1">
<filteringEndpointBehavior variation="1" />
</behavior>
<behavior name="endpoint2">
<filteringEndpointBehavior variation="2" />
</behavior>
</endpointBehaviors>
Enfin, le point de terminaison du service référence l'un des behaviorConfigurations
:
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint2" />
L'implémentation de l'application cliente est simple : elle crée deux canaux à l'URI du service (en passant cette valeur comme deuxième paramètre (via
) à CreateChannel(EndpointAddress)) et envoie un message unique sur chaque canal, mais utilise des adresses de point de terminaison différentes pour chacun d'entre eux. Par conséquent, les messages sortants provenant du client ont des désignations To différentes, et le serveur réagit en conséquence, tel qu'indiqué par la sortie du 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
Le passage d’une variante à une autre dans le fichier de configuration du serveur provoque la permutation du filtre et l’activation du comportement opposé sur le client (le message à urn:e
réussit, alors que le message à urn:a
échoue).
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint1" />
Pour configurer, générer et exécuter l'exemple
Pour générer la solution, suivez les instructions indiquées dans la rubrique Génération des exemples Windows Communication Foundation.
Pour exécuter l’exemple dans une configuration à une machine, suivez les instructions figurant dans Exécution des exemples Windows Communication Foundation.
Pour exécuter l’exemple dans une configuration inter-machines, suivez les instructions d’Exécution des exemples Windows Communication Foundation et modifiez la ligne suivante dans Client.cs.
Uri serviceVia = new Uri("http://localhost/ServiceModelSamples/service.svc");
Remplacez localhost par le nom du serveur.
Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");