Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O exemplo QueryStringFormatter demonstra como os pontos de extensibilidade do WCF (Windows Communication Foundation) podem ser usados para permitir dados de mensagem em um formato diferente do esperado pelo WCF. 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 é baseado no Guia de Início, que implementa o ICalculator contrato de serviço. Este exemplo demonstra como as mensagens de Adição, Subtração, Multiplicação e Divisão podem ser modificadas 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 distribuição de operações com base no nome da operação na solicitação GET.EnableHttpGetRequestsBehaviorcomportamento 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 ambiente de execução.
Neste exemplo, o cliente e o serviço são aplicativos de console (.exe).
Observação
O procedimento de instalação e as instruções de build para este exemplo estão localizados no final deste tópico.
Conceitos-chave
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 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 métodos Serialize e Deserialize.
Neste exemplo, QueryStringFormatter implementa ambas as interfaces e é implementada 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.SerializeRequestNo 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 propriedade Properties.No método
IDispatchMessageFormatter.DeserializeRequestno servidor, o formatador recupera o URIVianas propriedades da mensagem da solicitação recebida. Ele analisa os pares nome-valor na string de consulta da URI, convertendo-os em nomes e valores de parâmetros, e utiliza esses nomes e valores para preencher a matriz de parâmetros passada para o método. Observe que a expedição da operação já ocorreu, portanto, o sufixo de 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.
Classe UriPathSuffixOperationSelector
A IDispatchOperationSelector interface permite que os usuários implementem sua própria lógica para determinar a qual operação uma mensagem específica deve ser despachada.
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 método SelectOperation recebe a mensagem de entrada e encontra o Via URI nas propriedades da mensagem. Ele extrai o sufixo de nome da operação do URI, pesquisa uma tabela interna para obter o nome da operação para o qual a mensagem deve ser enviada e retorna o nome da operação.
Classe EnableHttpGetRequestsBehavior
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 é configurado para a implementação IDispatchOperationSelector.
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 específicos de formatador 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 executado após o padrão. No entanto, ele não pode ser configurado facilmente 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 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.ReplaceFormatterBehaviormé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 Open. Outra maneira de alcançar o mesmo resultado é derivar uma classe de ServiceHost que faça as chamadas para
EnableHttpGetRequestsBehavior.ReplaceFormatterBehaviorantes de abrir (consulte a documentação de hospedagem e amostras para exemplos).
Experiência do usuário
No servidor:
A implementação do servidor
ICalculatornão precisa ser alterada.O App.config do serviço deve usar uma associação POX personalizada que define o
messageVersionatributo dotextMessageEncodingelemento 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
EnableHttpGetRequestsBehavioradicionando-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 cliente deve usar uma associação POX personalizada que define o
messageVersionatributo dotextMessageEncodingelemento 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
EnableHttpGetRequestsBehaviorque o servidor.Adicionar formatores de operação antes de chamar CreateChannel().
Quando você executa o exemplo, as solicitações e respostas da operação 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
Verifique se você executou o Procedimento de instalação avulsa dos exemplos do Windows Communication Foundation.
Para criar a solução, siga as instruções na criação dos exemplos do Windows Communication Foundation.
Para executar o exemplo em uma configuração única ou entre máquinas, siga as instruções em Executando os exemplos do Windows Communication Foundation.