Operação Formatter 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, o WCF formatters espera que os parâmetros do soap:body
método sejam incluídos no elemento . O exemplo mostra como implementar um formatador de operação personalizado que analisa dados de parâmetro de uma cadeia de caracteres de consulta HTTP GET em vez disso e invoca métodos usando esses dados.
O exemplo é baseado na Introdução, que implementa o ICalculator
contrato de serviço. Ele mostra como Adicionar, Subtrair, Multiplicar e Dividir mensagens 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 e IDispatchMessageFormatter para o cliente e o servidor, respectivamente, e processa os dados na cadeia de IClientMessageFormatter caracteres de consulta.UriOperationSelector
, que implementa IDispatchOperationSelector no servidor para executar o despacho da operação com base no nome da operação na solicitação GET.EnableHttpGetRequestsBehavior
comportamento do ponto de extremidade (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 tempo de execução.
Neste exemplo, o cliente e o serviço são aplicativos de console (.exe).
Nota
O procedimento de configuração e as instruções de compilação para este exemplo estão localizados no final deste tópico.
Conceitos-chave
QueryStringFormatter
- O formatador de operação é o componente no WCF que é 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 IClientMessageFormatter interface e no servidor com a IDispatchMessageFormatter interface. Essas interfaces permitem que os usuários obtenham as mensagens de solicitação e resposta dos Serialize
métodos and Deserialize
.
Neste exemplo, QueryStringFormatter
implementa ambas as interfaces e é implementado no cliente e no servidor.
Pedido:
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 lançará uma exceção.
IClientMessageFormatter.SerializeRequest
No método no cliente, o formatador cria um URI com o endereço To apropriado e acrescenta o nome da operação como um sufixo. Esse nome é usado para despachar 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âmetros e os valores convertidos pela TypeConverter classe. As To propriedades e Via são definidas para esse URI. MessageProperties é acedido através da Properties propriedade.IDispatchMessageFormatter.DeserializeRequest
No método no servidor, o formatador recupera oVia
URI nas propriedades da mensagem de solicitação de entrada. Ele analisa os pares nome-valor na cadeia de caracteres de consulta URI em nomes e valores de parâmetros e usa os nomes e valores dos 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 nesse 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. Um dos objetivos deste exemplo é mostrar como esse formatador de delegação pode ser implementado.
UriPathSuffixOperationSelector Classe
A IDispatchOperationSelector interface permite que os usuários implementem sua própria lógica para a qual uma determinada mensagem 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 HTTP GET URI 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 pega a mensagem de entrada e procura o Via
URI em suas propriedades de mensagem. Ele extrai o sufixo do nome da operação do URI, procura uma tabela interna para obter o nome da operação para o qual a mensagem deve ser enviada e retorna esse nome da operação.
EnableHttpGetRequestsBehavior Classe
O UriPathSuffixOperationSelector
componente pode ser configurado programaticamente ou através de um comportamento de ponto final. O exemplo implementa o EnableHttpGetRequestsBehavior
comportamento, que é especificado no arquivo de configuração do aplicativo do serviço.
No servidor:
O OperationSelector está 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 a operação formatters
Os comportamentos de operação que especificam formatters 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 parecem apenas mais um comportamento de operação; eles não são identificáveis por qualquer outro atributo. Para instalar um comportamento de substituição, a implementação deve procurar comportamentos específicos do formatador 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 operação formatters 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 ponto de extremidade (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 ele 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 chamar 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 Open de ser chamado. Neste exemplo, mostramos como o formatador é modificado manualmente antes de chamar Openo . Outra maneira de conseguir a mesma coisa é derivar uma classe a partir da qual faz as chamadas antes
EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior
de abrir (consulte a documentação de ServiceHost hospedagem e exemplos para exemplos).
Experiência de utilizador
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
textMessageEncoding
atributo do 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 de 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>
Adicione a operação formatters antes de chamar Open.
No cliente:
A implementação do cliente não precisa mudar.
O App.config para o cliente deve usar uma associação POX personalizada que define o
messageVersion
textMessageEncoding
atributo do 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 Para 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.Adicione a operação formatters antes de chamar CreateChannel().
Quando você executa o exemplo, 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 ser bem-sucedidas.
Para configurar, compilar e executar o exemplo
Certifique-se de ter executado o procedimento de instalação única para os exemplos do Windows Communication Foundation.
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 ou cruzada, siga as instruções em Executando os exemplos do Windows Communication Foundation.