Formatador de operação e seletor de operação
O exemplo QueryStringFormatter demonstra como os pontos de extensibilidade do Windows Communication Foundation (WCF) podem ser usados para permitir dados de mensagem em um formato diferente do que o WCF espera. Por padrão, os formatadores WCF esperam que os parâmetros do método sejam incluídos no soap:body
elemento. A amostra mostra como implementar um formatador de operação personalizado que analisa dados de parâmetro de uma string de consulta HTTP GET e invoca métodos usando esses dados.
O exemplo baseia-se na Introdução, que implementa o contrato de serviço ICalculator
. Ele mostra como as mensagens Adicionar, Subtrair, Multiplicar e Dividir podem ser alteradas para usar HTTP GET para solicitações de cliente para servidor e HTTP POST com mensagens POX para respostas de servidor para cliente.
Para fazer isso, o exemplo fornece o seguinte:
QueryStringFormatter
, que implementa IClientMessageFormatter e IDispatchMessageFormatter para o cliente e o servidor, respectivamente, e processa os dados na cadeia de caracteres de consulta.UriOperationSelector
, que implementa IDispatchOperationSelector no servidor para executar a expedição de operação com base no nome da operação na solicitação GET.EnableHttpGetRequestsBehavior
comportamento do terminal (e configuração correspondente), que adiciona o seletor de operação necessário ao tempo de execução.Mostra como inserir um novo formatador de operação no runtime.
Neste exemplo, o cliente e o serviço são programas de console (.exe).
Observação
O procedimento de instalação e as instruções de compilação dessa amostra estão no final deste tópico.
Conceitos Principais
QueryStringFormatter
- O formatador de operação é o componente no WCF responsável por converter uma mensagem em uma matriz de objetos de parâmetro e uma matriz de objetos de parâmetro em uma mensagem. Isso é feito no cliente usando a IClientMessageFormatterinterface e no servidor com a IDispatchMessageFormatterinterface. Essas interfaces permitem que os usuários obtenham as mensagens de solicitação e resposta dos métodos Serialize
e Deserialize
.
Neste exemplo, QueryStringFormatter
implementa essas duas interfaces e é implementado no cliente e no servidor.
Solicitação:
O exemplo usa a TypeConverter classe para converter dados de parâmetro na mensagem de solicitação de e para cadeias de caracteres. Se um TypeConverter não estiver disponível para um tipo específico, o formatador de exemplo gerará uma exceção.
IClientMessageFormatter.SerializeRequest
No método no cliente, o formatador cria um URI com o endereço Apropriado para endereçar e acrescenta o nome da operação como um sufixo. Esse nome é usado para expedir para a operação apropriada no servidor. Em seguida, ele usa a matriz de objetos de parâmetro e serializa os dados de parâmetro para a cadeia de caracteres de consulta URI usando nomes de parâmetro e os valores convertidos pela TypeConverter classe. As propriedades To e Via estão definidas para esse valor. MessageProperties é acessado através da Properties propriedade.No
IDispatchMessageFormatter.DeserializeRequest
método no servidor, o formatador recupera oVia
URI nas propriedades da mensagem de solicitação recebida. Ele analisa os pares nome-valor na string de consulta do URI em nomes e valores de parâmetros e usa os nomes e valores de parâmetros para preencher a matriz de parâmetros passados para o método. Observe que o despacho da operação já ocorreu, portanto, o sufixo do nome da operação é ignorado neste método.
Resposta:
- Neste exemplo, HTTP GET é usado apenas para a solicitação. O formatador delega o envio da resposta ao formatador original que teria sido usado para gerar uma mensagem XML. Uma das metas deste exemplo é mostrar como esse formatador de delegação pode ser implementado.
UriPathSuffixOperationSelector Class
A IDispatchOperationSelector interface permite que os usuários implementem sua própria lógica para a qual a operação uma mensagem específica deve ser enviada.
Neste exemplo, UriPathSuffixOperationSelector
deve ser implementado no servidor para selecionar a operação apropriada porque o nome da operação está incluído no URI HTTP GET em vez de um cabeçalho de ação na mensagem. O exemplo é configurado para permitir apenas nomes de operação que não diferenciam maiúsculas de minúsculas.
O SelectOperation
método usa a mensagem de entrada e pesquisa o Via
URI em suas propriedades de mensagem. Ele extrai o sufixo do nome da operação do URI, consulta uma tabela interna para obter o nome da operação para a qual a mensagem deve ser despachada e retorna esse nome de operação.
EnableHttpGetRequestsBehavior Class
O UriPathSuffixOperationSelector
componente pode ser configurado programaticamente ou por meio de um comportamento de ponto de extremidade. O exemplo implementa o EnableHttpGetRequestsBehavior
comportamento, que é especificado no arquivo de configuração de aplicativo do serviço.
No servidor:
O OperationSelector é definido para a IDispatchOperationSelector implementação.
Por padrão, o WCF usa um filtro de endereço de correspondência exata. O URI na mensagem de entrada contém um sufixo de nome de operação seguido por uma cadeia de caracteres de consulta que contém dados de parâmetro, portanto, o comportamento do ponto de extremidade também altera o filtro de endereço para ser um filtro de correspondência de prefixo. Ele usa o WCFPrefixEndpointAddressMessageFilter para essa finalidade.
Instalando formatadores de operação
Os comportamentos de operação que especificam formatadores são exclusivos. Um desses comportamentos é sempre implementado por padrão para cada operação para criar o formatador de operação necessário. No entanto, esses comportamentos se parecem apenas com outro comportamento de operação; eles não são identificáveis por nenhum outro atributo. Para instalar um comportamento de substituição, a implementação deve procurar comportamentos de formatador específicos que são instalados pelo carregador de tipo WCF por padrão e substituí-lo ou adicionar um comportamento compatível para ser executado após o comportamento padrão.
Esses comportamentos de formatadores de operação podem ser configurados programaticamente antes da chamada CommunicationObject.Open ou especificando um comportamento de operação que é executado após o padrão. No entanto, ele não pode ser facilmente configurado por um comportamento de terminal (e, portanto, por configuração) porque o modelo de comportamento não permite que um comportamento substitua outros comportamentos ou modifique a árvore de descrição.
No cliente:
A IClientMessageFormatter implementação deve ser implementada para que possa converter as solicitações em solicitações HTTP GET e delegar ao formatador original para respostas. Isso é feito chamando o EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior
método auxiliar.
Isso deve ser feito antes de ligar CreateChannel
.
void ReplaceFormatterBehavior(OperationDescription operationDescription, EndpointAddress address)
{
// Remove the DataContract behavior if it is present.
IOperationBehavior formatterBehavior = operationDescription.Behaviors.Remove<DataContractSerializerOperationBehavior>();
if (formatterBehavior == null)
{
// Remove the XmlSerializer behavior if it is present.
formatterBehavior = operationDescription.Behaviors.Remove<XmlSerializerOperationBehavior>();
...
}
// Remember what the innerFormatterBehavior was.
DelegatingFormatterBehavior delegatingFormatterBehavior = new DelegatingFormatterBehavior(address);
delegatingFormatterBehavior.InnerFormatterBehavior = formatterBehavior;
operationDescription.Behaviors.Add(delegatingFormatterBehavior);
}
No servidor:
A IDispatchMessageFormatter interface deve ser implementada para que possa ler solicitações HTTP GET e delegar ao formatador original para escrever respostas. Isso é feito chamando o mesmo
EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior
método auxiliar que o cliente (consulte o exemplo de código anterior).Isso deve ser feito antes de Open ser chamado. Neste exemplo, mostramos como o formatador é modificado manualmente antes de chamar Open. Outra maneira de conseguir a mesma coisa é derivar uma classe de ServiceHost que faz as chamadas
EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior
antes de abrir (consulte a documentação de hospedagem e exemplos para obter exemplos).
Experiência do usuário
No servidor:
A implementação do servidor
ICalculator
não precisa ser alterada.O App.config para o serviço deve usar uma associação POX personalizada que define o
messageVersion
atributo dotextMessageEncoding
elemento comoNone
.<bindings> <customBinding> <binding name="poxBinding"> <textMessageEncoding messageVersion="None" /> <httpTransport /> </binding> </customBinding> </bindings>
O App.config para o serviço também deve especificar o personalizado
EnableHttpGetRequestsBehavior
adicionando-o à seção extensões de comportamento e usando-o.<behaviors> <endpointBehaviors> <behavior name="enableHttpGetRequestsBehavior"> <enableHttpGetRequests /> </behavior> </endpointBehaviors> </behaviors> <extensions> <behaviorExtensions> <!-- Enabling HTTP GET requests: Behavior Extension --> <add name="enableHttpGetRequests" type="Microsoft.ServiceModel.Samples.EnableHttpGetRequestsBehaviorElement, QueryStringFormatter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions>
Adicionar formatores de operação antes de chamar Open.
No cliente:
A implementação do cliente não precisa ser alterada.
O App.config para o serviço deve usar uma associação POX personalizada que define o
messageVersion
atributo dotextMessageEncoding
elemento comoNone
. Uma diferença do serviço é que o cliente deve habilitar o endereçamento manual para que o endereço de saída possa ser modificado.<bindings> <customBinding> <binding name="poxBinding"> <textMessageEncoding messageVersion="None" /> <httpTransport manualAddressing="True" /> </binding> </customBinding> </bindings>
O App.config para o cliente deve especificar o mesmo personalizado
EnableHttpGetRequestsBehavior
que o servidor.Adicionar formatores de operação antes de chamar CreateChannel().
Quando você executa a amostra, as solicitações de operação e as respostas são exibidas na janela do console do cliente. Todas as quatro operações (Adicionar, Subtrair, Multiplicar e Dividir) devem ter êxito.
Para configurar, compilar, e executar o exemplo
Verifique se você executou o Procedimento de instalação única para os exemplos do Windows Communication Foundation.
Para compilar a solução, siga as instruções contidas em Como compilar as amostras do Windows Communication Foundation.
Para executar a amostra em uma configuração de computador único ou entre computadores, siga as instruções contidas em Como executar as amostras do Windows Communication Foundation.