Compartilhar via


Como: publicar metadados utilizando código para um serviço

Este é um dos dois tópicos de instruções que discutem a publicação de metadados para um serviço do WCF (Windows Communication Foundation). Há duas maneiras de especificar como um serviço deve publicar metadados, usando um arquivo de configuração e usando código. Este tópico mostra como publicar metadados para um serviço usando um código.

Cuidado

Este tópico mostra como publicar metadados de maneira não segura. Qualquer cliente pode recuperar os metadados do serviço. Se você precisar que seu serviço publique metadados de maneira segura. confira Ponto de extremidade de metadados seguros personalizados.

Para obter mais informações sobre como publicar metadados em um arquivo de configuração, consulte Como publicar metadados para um serviço usando um arquivo de configuração. Publicar metadados permite que os clientes recuperem os metadados usando uma solicitação GET WS-Transfer ou uma solicitação HTTP/GET usando a cadeia de caracteres de consulta ?wsdl. Para ter certeza de que o código está funcionando, você deve criar um serviço WCF básico. Um serviço auto-hospedado básico é fornecido no código a seguir.

using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Metadata.Samples
{
    [ServiceContract]
    public interface ISimpleService
    {
        [OperationContract]
        string SimpleMethod(string msg);
    }

    class SimpleService : ISimpleService
    {
        public string SimpleMethod(string msg)
        {
            Console.WriteLine("The caller passed in " + msg);
            return "Hello " + msg;
        }
    }
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description

<ServiceContract()> _
Public Interface ISimpleService
    <OperationContract()> _
    Function SimpleMethod(ByVal msg As String) As String
End Interface

Class SimpleService
    Implements ISimpleService

    Public Function SimpleMethod(ByVal msg As String) As String Implements ISimpleService.SimpleMethod
        Console.WriteLine("The caller passed in " + msg)
        Return "Hello " + msg
    End Function
End Class

Para publicar metadados no código

  1. Dentro do método principal de um aplicativo de console, instancie um objeto ServiceHost passando o tipo de serviço e o endereço base.

    ServiceHost svcHost = new ServiceHost(typeof(SimpleService), new Uri("http://localhost:8001/MetadataSample"));
    
    Dim svcHost As New ServiceHost(GetType(SimpleService), New Uri("http://localhost:8001/MetadataSample"))
    
  2. Crie um bloco de tentativa imediatamente abaixo do código para a etapa 1, isso captura todas as exceções que são lançadas enquanto o serviço estiver em execução.

    try
    {
    
    Try
    
    }
    catch (CommunicationException commProblem)
    {
        Console.WriteLine("There was a communication problem. " + commProblem.Message);
        Console.Read();
    }
    
    Catch commProblem As CommunicationException
    
        Console.WriteLine("There was a communication problem. " + commProblem.Message)
        Console.Read()
    End Try
    
  3. Verifique se o host de serviço já contém uma ServiceMetadataBehavior, caso contrário, crie uma nova instância ServiceMetadataBehavior.

    // Check to see if the service host already has a ServiceMetadataBehavior
    ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
    // If not, add one
    if (smb == null)
        smb = new ServiceMetadataBehavior();
    
    'Check to see if the service host already has a ServiceMetadataBehavior
    Dim smb As ServiceMetadataBehavior = svcHost.Description.Behaviors.Find(Of ServiceMetadataBehavior)()
    'If not, add one
    If (smb Is Nothing) Then
        smb = New ServiceMetadataBehavior()
    End If
    
  4. Defina a propriedade HttpGetEnabled como true.

    smb.HttpGetEnabled = true;
    
    smb.HttpGetEnabled = True
    
  5. O ServiceMetadataBehavior contém uma propriedade MetadataExporter. O MetadataExporter contém uma propriedade PolicyVersion. Defina o valor da propriedade PolicyVersion como Policy15. A propriedade PolicyVersion também pode ser definida como Policy12. Quando definido como Policy15, o exportador de metadados gera informações de política com os metadados que estão em conformidade com a WS-Policy 1.5. Quando definido como Policy12, o exportador de metadados gera informações de política com os metadados que" estão em conformidade com a WS-Policy 1.2.

    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
    
    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
    
  6. Adicione a instância ServiceMetadataBehavior à coleção de comportamentos do host de serviço.

    svcHost.Description.Behaviors.Add(smb);
    
    svcHost.Description.Behaviors.Add(smb)
    
  7. Adicione o ponto de extremidade de troca de metadados ao host de serviço.

    // Add MEX endpoint
    svcHost.AddServiceEndpoint(
      ServiceMetadataBehavior.MexContractName,
      MetadataExchangeBindings.CreateMexHttpBinding(),
      "mex"
    );
    
    'Add MEX endpoint
    svcHost.AddServiceEndpoint( _
          ServiceMetadataBehavior.MexContractName, _
          MetadataExchangeBindings.CreateMexHttpBinding(), _
          "mex")
    
  8. Adicione um ponto de extremidade de aplicativo ao host de serviço.

    // Add application endpoint
    svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
    
    'Add application endpoint
    svcHost.AddServiceEndpoint(GetType(ISimpleService), New WSHttpBinding(), "")
    

    Observação

    Se você não adicionar nenhum ponto de extremidade ao serviço, o runtime adicionará pontos de extremidade padrão para você. Neste exemplo, como o serviço tem ServiceMetadataBehavior definido como true, o serviço possui metadados de publicação habilitados. Para obter mais informações sobre pontos de extremidade padrão, consulte Configuração simplificada e Configuração simplificada para serviços WCF.

  9. Abra o host de serviço e aguarde as chamadas recebidas. Quando o usuário pressionar ENTER, feche o host de serviço.

    // Open the service host to accept incoming calls
    svcHost.Open();
    
    // The service can now be accessed.
    Console.WriteLine("The service is ready.");
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.WriteLine();
    Console.ReadLine();
    
    // Close the ServiceHostBase to shutdown the service.
    svcHost.Close();
    
    'Open the service host to accept incoming calls
    svcHost.Open()
    
    'The service can now be accessed.
    Console.WriteLine("The service is ready.")
    Console.WriteLine("Press <ENTER> to terminate service.")
    Console.WriteLine()
    Console.ReadLine()
    
    'Close the ServiceHostBase to shutdown the service.
    svcHost.Close()
    
  10. Crie e execute o aplicativo de console.

  11. Navegue até o endereço base do serviço (http://localhost:8001/MetadataSample neste exemplo) e verificar se a publicação de metadados está ativada. Deve ser exibida uma página da Web que diz "Serviço Simples" na parte superior e imediatamente abaixo "Você criou um serviço". Caso contrário, uma mensagem na parte superior da página resultante será exibida: "A publicação de metadados para esse serviço está desabilitada no momento".

Exemplo

O exemplo de código a seguir mostra a implementação de um serviço WCF básico que publica metadados para o serviço no código.

using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Metadata.Samples
{
    [ServiceContract]
    public interface ISimpleService
    {
        [OperationContract]
        string SimpleMethod(string msg);
    }

    class SimpleService : ISimpleService
    {
        public string SimpleMethod(string msg)
        {
            Console.WriteLine("The caller passed in " + msg);
            return "Hello " + msg;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost svcHost = new ServiceHost(typeof(SimpleService), new Uri("http://localhost:8001/MetadataSample"));
            try
            {
                // Check to see if the service host already has a ServiceMetadataBehavior
                ServiceMetadataBehavior smb = svcHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
                // If not, add one
                if (smb == null)
                    smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                svcHost.Description.Behaviors.Add(smb);
                // Add MEX endpoint
                svcHost.AddServiceEndpoint(
                  ServiceMetadataBehavior.MexContractName,
                  MetadataExchangeBindings.CreateMexHttpBinding(),
                  "mex"
                );
                // Add application endpoint
                svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
                // Open the service host to accept incoming calls
                svcHost.Open();

                // The service can now be accessed.
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

                // Close the ServiceHostBase to shutdown the service.
                svcHost.Close();
            }
            catch (CommunicationException commProblem)
            {
                Console.WriteLine("There was a communication problem. " + commProblem.Message);
                Console.Read();
            }
        }
    }
}
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description

<ServiceContract()> _
Public Interface ISimpleService
    <OperationContract()> _
    Function SimpleMethod(ByVal msg As String) As String
End Interface

Class SimpleService
    Implements ISimpleService

    Public Function SimpleMethod(ByVal msg As String) As String Implements ISimpleService.SimpleMethod
        Console.WriteLine("The caller passed in " + msg)
        Return "Hello " + msg
    End Function
End Class

Module Module1

    Sub Main()
        Dim svcHost As New ServiceHost(GetType(SimpleService), New Uri("http://localhost:8001/MetadataSample"))
        Try
            'Check to see if the service host already has a ServiceMetadataBehavior
            Dim smb As ServiceMetadataBehavior = svcHost.Description.Behaviors.Find(Of ServiceMetadataBehavior)()
            'If not, add one
            If (smb Is Nothing) Then
                smb = New ServiceMetadataBehavior()
            End If
            smb.HttpGetEnabled = True
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
            svcHost.Description.Behaviors.Add(smb)
            'Add MEX endpoint
            svcHost.AddServiceEndpoint( _
                  ServiceMetadataBehavior.MexContractName, _
                  MetadataExchangeBindings.CreateMexHttpBinding(), _
                  "mex")
            'Add application endpoint
            svcHost.AddServiceEndpoint(GetType(ISimpleService), New WSHttpBinding(), "")
            'Open the service host to accept incoming calls
            svcHost.Open()

            'The service can now be accessed.
            Console.WriteLine("The service is ready.")
            Console.WriteLine("Press <ENTER> to terminate service.")
            Console.WriteLine()
            Console.ReadLine()

            'Close the ServiceHostBase to shutdown the service.
            svcHost.Close()
        Catch commProblem As CommunicationException

            Console.WriteLine("There was a communication problem. " + commProblem.Message)
            Console.Read()
        End Try
    End Sub
End Module

Confira também