Partilhar via


Operação Formatador e Operação Seletor

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 do WCF esperam que os parâmetros do método sejam incluídos no elemento soap:body. 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 no Guia de Início, que implementa o contrato de serviço ICalculator. 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 IClientMessageFormatter e IDispatchMessageFormatter para o cliente e o servidor, respectivamente, e processa os dados na cadeia 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 introduzir um novo formatador de operações durante a execução.

  • Neste exemplo, o cliente e o serviço são aplicativos de console (.exe).

Observação

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 métodos Serialize e 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.

  • No método IClientMessageFormatter.SerializeRequest do cliente, o formatador cria um URI com o endereço apropriado para "To" e acrescenta o nome da operação como sufixo. Esse nome é usado para encaminhar à operação correspondente no servidor. Em seguida, ele usa a matriz de objetos de parâmetros e serializa os dados dos parâmetros para a string da consulta URI usando nomes de parâmetros e os valores convertidos pela classe TypeConverter. As propriedades To e Via são configuradas para este URI. MessageProperties é acedido através da propriedade Properties.

  • IDispatchMessageFormatter.DeserializeRequest No método no servidor, o formatador recupera o Via 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 interface IDispatchOperationSelector permite que os utilizadores implementem a sua própria lógica relativamente a que operação uma dada mensagem 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 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 recebe a mensagem de entrada e procura o Via URI nas propriedades da 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.

Classe EnableHttpGetRequestsBehavior

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 da mensagem de entrada contém um nome de operação como sufixo seguido por uma cadeia de consulta com dados de parâmetros, assim, o comportamento do ponto de extremidade altera também o filtro de endereço para um filtro de correspondência de prefixo. Ele usa o WCFPrefixEndpointAddressMessageFilter para essa finalidade.

Instalação de formatadores de operação

Os comportamentos operacionais que especificam formatadores são únicos. 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 dos formatadores de operações podem ser configurados programaticamente antes da chamada de CommunicationObject.Open, ou ao especificar um comportamento de operação que seja 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.

Sobre o 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 Open. Outra maneira de conseguir a mesma coisa é derivar uma classe a partir de ServiceHost que faz as chamadas a EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior antes de abrir (consulte a documentação de hospedagem e os exemplos para exemplos).

Experiência do 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 atributo messageVersion do elemento textMessageEncoding para None.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    
  • O App.config para o serviço também deve especificar o EnableHttpGetRequestsBehavior personalizado ao adicioná-lo na seção de extensões de comportamento e utilizá-lo.

    <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 formatters de operação antes de chamar Open.

Sobre o 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 atributo messageVersion do elemento textMessageEncoding como None. Uma diferença no serviço é que o cliente deve ativar o endereçamento manual para que o endereço de destinatário possa ser modificado.

    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport manualAddressing="True" />
        </binding>
      </customBinding>
    </bindings>
    
  • O App.config do cliente deve especificar o mesmo parâmetro personalizado EnableHttpGetRequestsBehavior que o servidor.

  • Adicione formatters de operação 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
  1. Verifique se você executou o procedimento de instalação do One-Time para os exemplos do Windows Communication Foundation.

  2. Para criar a solução, siga as instruções em Criando os exemplos do Windows Communication Foundation.

  3. 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.