Visão geral da arquitetura de metadados

O WCF (Windows Communication Foundation) fornece uma infraestrutura avançada para exportar, publicar, recuperar e importar metadados do serviço. Os serviços WCF usam metadados para descrever como interagir com os pontos de extremidade do serviço para que ferramentas, como Svcutil.exe, possam gerar automaticamente o código do cliente para acessar o serviço.

A maioria dos tipos que compõem a infraestrutura de metadados do WCF reside no namespace System.ServiceModel.Description.

O WCF usa a classe ServiceEndpoint para descrever pontos de extremidade em um serviço. Você pode usar o WCF para gerar metadados para pontos de extremidade de serviço ou importar metadados de serviço para gerar instâncias ServiceEndpoint.

O WCF representa os metadados de um serviço como uma instância do tipo MetadataSet, a estrutura da qual está fortemente vinculada ao formato de serialização de metadados definido no WS-MetadataExchange. O tipo MetadataSet agrupa os metadados de serviço reais, como documentos WSDL (Web Services Description Language), documentos de esquema XML ou expressões de WS-Policy, como uma coleção de instâncias MetadataSection. Cada instância System.ServiceModel.Description.MetadataSection contém um dialeto e um identificador de metadados específicos. System.ServiceModel.Description.MetadataSection pode conter os seguintes itens em sua propriedade MetadataSection.Metadata:

Uma instância System.ServiceModel.Description.MetadataReference aponta para outro ponto de extremidade MEX (troca de metadados) e instâncias System.ServiceModel.Description.MetadataLocation apontam para um documento de metadados usando uma URL HTTP. O WCF dá suporte ao uso de documentos WSDL para descrever pontos de extremidade de serviço, contratos de serviço, associações, padrões de troca de mensagens, mensagens e mensagens de falha implementadas por um serviço. Os tipos de dados usados pelo serviço são descritos em documentos WSDL usando o esquema XML. Para obter mais informações, consulte Importação e exportação de esquemas. Você pode usar o WCF para exportar e importar extensões WSDL para comportamento de serviço, comportamentos de contrato e elementos de associação que estendem a funcionalidade de um serviço. Para obter mais informações, consulte Exportando metadados personalizados para uma extensão WCF.

Exportando metadados de serviço

No WCF, exportação de metadados é o processo de descrever pontos de extremidade de serviço e projetá-los em uma representação paralela e padronizada que os clientes podem usar para entender como usar o serviço. Para exportar metadados de instâncias ServiceEndpoint, use uma implementação da classe abstrata MetadataExporter. Uma implementação System.ServiceModel.Description.MetadataExporter gera metadados encapsulados em uma instância MetadataSet.

A classe System.ServiceModel.Description.MetadataExporter fornece uma estrutura para gerar expressões de política que descrevem os recursos e requisitos de uma associação de ponto de extremidade e suas operações, mensagens e falhas associadas. Essas expressões de política são capturadas em uma instância PolicyConversionContext. Uma implementação System.ServiceModel.Description.MetadataExporter pode anexar essas expressões de política aos metadados gerados.

System.ServiceModel.Description.MetadataExporter chama cada System.ServiceModel.Channels.BindingElement que implementa a interface IPolicyExportExtension na associação de um ServiceEndpoint ao gerar um objeto PolicyConversionContext para a implementação System.ServiceModel.Description.MetadataExporter a ser usada. Você pode exportar novas declarações de política implementando a interface IPolicyExportExtension em suas implementações personalizadas do tipo BindingElement.

O tipo WsdlExporter é a implementação da classe abstrata System.ServiceModel.Description.MetadataExporter incluída no WCF. O tipo WsdlExporter gera metadados WSDL com expressões de política anexadas.

Para exportar metadados personalizados WSDL ou extensões WSDL para comportamentos de ponto de extremidade, comportamentos de contrato ou elementos de associação em um ponto de extremidade de serviço, você pode implementar a interface IWsdlExportExtension. WsdlExporter considera uma instância ServiceEndpoint para elementos de associação, comportamentos de operação, comportamentos de contrato e comportamentos de ponto de extremidade que implementam a interface IWsdlExportExtension ao gerar o documento WSDL.

Publicando metadados de serviço

Os serviços WCF publicam metadados expondo um ou mais pontos de extremidade de metadados. Os metadados do serviço de publicação disponibilizam metadados de serviço usando protocolos padronizados, como solicitações MEX e HTTP/GET. Os pontos de extremidade de metadados são semelhantes a outros pontos de extremidade de serviço, pois eles têm um endereço, uma associação e um contrato. Você pode adicionar pontos de extremidade de metadados a um host de serviço na configuração ou no código.

Para publicar pontos de extremidade de metadados para um serviço WCF, primeiro você deve adicionar uma instância do comportamento do serviço ServiceMetadataBehavior ao serviço. Adicionar uma instância System.ServiceModel.Description.ServiceMetadataBehavior ao serviço aumenta seu serviço com a capacidade de publicar metadados expondo um ou mais pontos de extremidade de metadados. Depois de adicionar o comportamento do serviço System.ServiceModel.Description.ServiceMetadataBehavior, você poderá expor pontos de extremidade de metadados que dão suporte ao protocolo MEX ou pontos de extremidade de metadados que respondem a solicitações HTTP/GET.

Para adicionar pontos de extremidade de metadados que usam o protocolo MEX, adicione pontos de extremidade de serviço ao host de serviço que usa o contrato de serviço chamado IMetadataExchange. WCF define a interface IMetadataExchange que tem esse nome de contrato de serviço. Os pontos de extremidade WS-MetadataExchange, ou pontos de extremidade MEX, podem usar uma das quatro associações padrão que os métodos de fábrica estáticos expõem na classe MetadataExchangeBindings para corresponder às associações padrão usadas por ferramentas do WCF, como Svcutil.exe. Você também pode configurar pontos de extremidade de metadados MEX usando uma associação personalizada.

O ServiceMetadataBehavior usa um System.ServiceModel.Description.WsdlExporter para exportar metadados para todos os pontos de extremidade de serviço no seu serviço. Para obter mais informações sobre como exportar metadados de um serviço, consulte Exportando e importando metadados.

ServiceMetadataBehavior aumenta o host de serviço adicionando uma instância ServiceMetadataExtension como uma extensão ao host de serviço. System.ServiceModel.Description.ServiceMetadataExtension fornece a implementação para os protocolos de publicação de metadados. Você também pode usar System.ServiceModel.Description.ServiceMetadataExtension para obter os metadados do serviço no tempo de execução acessando a propriedade Metadata.

Cuidado

Se adicionar um ponto de extremidade MEX no arquivo de configuração do aplicativo e tentar adicionar ServiceMetadataBehavior ao host de serviço no código, você receberá a seguinte exceção:

System.InvalidOperationException: o nome do contrato 'IMetadataExchange' não pôde ser encontrado na lista de contratos implementados pelo serviço Service1. Adicione um ServiceMetadataBehavior ao arquivo de configuração ou ao ServiceHost diretamente para habilitar o suporte para esse contrato.

Você pode contornar esse problema adicionando ServiceMetadataBehavior no arquivo de configuração ou adicionando o ponto de extremidade e ServiceMetadataBehavior no código.

Para obter um exemplo de adição de ServiceMetadataBehavior em um arquivo de configuração de aplicativo, consulte a Introdução. Para obter um exemplo de adição de ServiceMetadataBehavior no código, consulte o exemplo de Auto-hospedagem.

Cuidado

Ao publicar metadados para um serviço que expõe dois contratos de serviço diferentes nos quais cada um contém uma operação de mesmo nome, uma exceção é gerada. Por exemplo, se você tiver um serviço que expõe um contrato de serviço chamado ICarService que tem uma operação Get(Car c) e o mesmo serviço expuser um contrato de serviço chamado IBookService que tem uma operação Get(Book b), uma exceção será gerada, ou uma mensagem de erro será exibida ao se gerar os metadados do serviço. Para contornar esse problema, adote uma das seguintes medidas:

  • Renomeie uma das operações.
  • Defina o Name com um nome diferente.
  • Defina um dos namespaces das operações como um namespace diferente usando a propriedade Namespace.

Recuperando metadados de serviço

O WCF pode recuperar metadados de serviço usando protocolos padronizados, como WS-MetadataExchange e HTTP. Ambos os protocolos são compatíveis com o tipo MetadataExchangeClient. Você recupera metadados de serviço usando o tipo System.ServiceModel.Description.MetadataExchangeClient fornecendo um endereço e uma associação opcional. A associação usada por uma instância System.ServiceModel.Description.MetadataExchangeClient pode ser uma das associações padrão da classe estática MetadataExchangeBindings, uma associação fornecida pelo usuário ou uma associação carregada de uma configuração de ponto de extremidade para o contrato IMetadataExchange. O System.ServiceModel.Description.MetadataExchangeClient também pode resolver referências de URL HTTP para metadados usando o tipo HttpWebRequest.

Por padrão, uma instância System.ServiceModel.Description.MetadataExchangeClient está vinculada a uma única instância ChannelFactoryBase. Você pode alterar ou substituir a instância ChannelFactoryBase usada por um System.ServiceModel.Description.MetadataExchangeClient substituindo o método virtual GetChannelFactory. Da mesma forma, você pode alterar ou substituir a instância System.Net.HttpWebRequest usada por um System.ServiceModel.Description.MetadataExchangeClient para fazer solicitações HTTP/GET substituindo o método virtual MetadataExchangeClient.GetWebRequest.

Você pode recuperar metadados de serviço usando WS-MetadataExchange ou solicitações HTTP/GET usando a ferramenta Svcutil.exe e passando a opção /target:metadata e um endereço. Svcutil.exe baixa os metadados no endereço especificado e salva os arquivos no disco. Svcutil.exe usa uma instância System.ServiceModel.Description.MetadataExchangeClient internamente e carrega uma configuração de ponto de extremidade MEX (do arquivo de configuração do aplicativo) cujo nome corresponde ao esquema do endereço passado para Svcutil.exe, se houver. Caso contrário, Svcutil.exe padrão usar uma das associações definidas pelo tipo de alocador estático MetadataExchangeBindings.

Importando metadados de serviço

No WCF, a importação de metadados é o processo de geração de uma representação abstrata de um serviço ou de suas partes componentes de seus metadados. Por exemplo, o WCF pode importar instâncias ServiceEndpoint, Binding ou ContractDescription de um documento WSDL para um serviço. Para importar metadados de serviço no WCF, use uma implementação de classe abstrata MetadataImporter. Tipos que derivam da classe System.ServiceModel.Description.MetadataImporter implementam suporte para importação de formatos de metadados que aproveitam a lógica de importação WS-Policy no WCF.

Uma implementação System.ServiceModel.Description.MetadataImporter coleta as expressões de política anexadas aos metadados de serviço em um objeto PolicyConversionContext. Em seguida, System.ServiceModel.Description.MetadataImporter processa as políticas como parte da importação dos metadados chamando as implementações da interface IPolicyImportExtension na propriedade PolicyImportExtensions.

Você pode adicionar suporte para importar novas declarações de política a um System.ServiceModel.Description.MetadataImporter adicionando sua própria implementação da interface IPolicyImportExtension à coleção PolicyImportExtensions em uma instância System.ServiceModel.Description.MetadataImporter. Como alternativa, você pode registrar sua extensão de importação de política no arquivo de configuração do aplicativo cliente.

O tipo System.ServiceModel.Description.WsdlImporter é a implementação da classe abstrata System.ServiceModel.Description.MetadataImporter incluída no WCF. O tipo System.ServiceModel.Description.WsdlImporter importa metadados WSDL com políticas anexadas que são empacotadas em um objeto MetadataSet.

Você pode adicionar suporte para importar extensões WSDL implementando a interface IWsdlImportExtension e adicionando sua implementação à propriedade WsdlImportExtensions em sua instância System.ServiceModel.Description.WsdlImporter. System.ServiceModel.Description.WsdlImporter pode também carregar implementações da interface System.ServiceModel.Description.IWsdlImportExtension registrada no arquivo de configuração do aplicativo cliente.

Associações dinâmicas

Você poderá atualizar dinamicamente a associação que usa para criar um canal para um ponto de extremidade de serviço caso a associação para o ponto de extremidade seja alterada ou você queira criar um canal para um ponto de extremidade que use o mesmo contrato, mas tenha uma associação diferente. Você pode usar a classe estática MetadataResolver para recuperar e importar metadados no tempo de execução para pontos de extremidade de serviço que implementam um contrato específico. Em seguida, você pode usar os objetos importados System.ServiceModel.Description.ServiceEndpoint para criar um cliente ou fábrica de canais para o ponto de extremidade desejado.

Confira também