Filtro de Mensagens Personalizado
O exemplo MessageFilter demonstra como substituir os filtros de mensagem que o Windows Communication Foundation (WCF) usa para enviar mensagens para pontos de extremidade.
Nota
O procedimento de configuração e as instruções de compilação para este exemplo estão localizados no final deste tópico.
Quando a primeira mensagem em um canal chega ao servidor, o servidor deve determinar qual (se houver) dos pontos de extremidade associados a esse URI deve receber a mensagem. Esse processo é controlado pelos MessageFilter objetos anexados ao EndpointDispatcher.
Cada ponto de extremidade de um serviço tem um único EndpointDispatcher. O EndpointDispatcher tem um AddressFilter e um ContractFilter. A união desses dois filtros é o filtro de mensagem usado para esse ponto de extremidade.
Por padrão, o AddressFilter para um ponto de extremidade corresponde a qualquer mensagem endereçada a um endereço que corresponda ao ponto de EndpointAddressextremidade do serviço. Por padrão, o ContractFilter para um ponto de extremidade inspeciona a ação da mensagem de entrada e faz a correspondência de qualquer mensagem com uma ação que corresponde a uma das ações das operações do contrato de ponto de extremidade de serviço (apenas IsInitiating
=true
as ações são consideradas). Como resultado, por padrão, o filtro de um ponto de extremidade só corresponde se o cabeçalho Para da mensagem for o EndpointAddress do ponto de extremidade e a ação da mensagem corresponder a uma das ações da operação do ponto de extremidade.
Esses filtros podem ser alterados usando um comportamento. No exemplo, o serviço cria um IEndpointBehavior que substitui o AddressFilter e ContractFilter no EndpointDispatcher:
class FilteringEndpointBehavior : IEndpointBehavior
{
//...
}
Dois filtros de endereço são definidos:
// 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 { }
O FilteringEndpointBehavior
é feito configurável e permite duas variações diferentes.
public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement { }
A Variação 1 corresponde apenas aos endereços que contêm um 'e' (mas que têm qualquer Ação), enquanto a Variação 2 corresponde apenas aos endereços que não têm um 'e':
if (Variation == 1)
return new FilteringEndpointBehavior(
new MatchEAddressFilter(), new MatchAllMessageFilter());
else
return new FilteringEndpointBehavior(
new MatchNoEAddressFilter(), new MatchAllMessageFilter());
No arquivo de configuração, o serviço registra o novo comportamento:
<extensions>
<behaviorExtensions>
<add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
</behaviorExtensions>
</extensions>
Em seguida, o serviço cria endpointBehavior
configurações para cada variação:
<endpointBehaviors>
<behavior name="endpoint1">
<filteringEndpointBehavior variation="1" />
</behavior>
<behavior name="endpoint2">
<filteringEndpointBehavior variation="2" />
</behavior>
</endpointBehaviors>
Finalmente, o ponto de extremidade do serviço faz referência a um dos behaviorConfigurations
seguintes:
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint2" />
A implementação da aplicação cliente é simples; ele cria dois canais para o URI do serviço (passando esse valor como o segundo parâmetro (via
) para CreateChannel(EndpointAddress) e envia uma única mensagem em cada canal, mas usa endereços de ponto de extremidade diferentes para cada um. Como resultado, as mensagens de saída do cliente têm designações To diferentes, e o servidor responde de acordo, conforme demonstrado pela saída do cliente:
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
Alternar a variação no arquivo de configuração do servidor faz com que o filtro seja trocado e o cliente vê o comportamento oposto (a mensagem para urn:e
ter êxito, enquanto a mensagem para urn:a
falhar).
<endpoint address=""
bindingConfiguration="ws"
listenUri=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.IHello"
behaviorConfiguration="endpoint1" />
Para configurar, compilar e executar o exemplo
Para criar a solução, siga as instruções em Criando os exemplos do Windows Communication Foundation.
Para executar o exemplo em uma configuração de máquina única, siga as instruções em Executando os exemplos do Windows Communication Foundation.
Para executar o exemplo em uma configuração entre máquinas, siga as instruções em Executando os exemplos do Windows Communication Foundation e altere a seguinte linha no Client.cs.
Uri serviceVia = new Uri("http://localhost/ServiceModelSamples/service.svc");
Substitua localhost pelo nome do servidor.
Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");