Como: Publicar metadados para um serviço usando código

Este é um dos dois tópicos de instruções que discutem a publicação de metadados para um serviço 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.

Atenção

Este tópico mostra como publicar metadados de forma não segura. Qualquer cliente pode recuperar os metadados do serviço. Se você precisar que seu serviço publique metadados de forma segura. consulte 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. A publicação de metadados permite que os clientes recuperem os metadados usando uma solicitação WS-Transfer GET ou uma solicitação HTTP/GET usando a cadeia de caracteres de ?wsdl consulta. 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 ServiceHost objeto 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 deteta todas as exceções que são lançadas enquanto o serviço está 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 um ServiceMetadataBehavior, caso contrário, crie uma nova ServiceMetadataBehavior instância.

    // 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 HttpGetEnabled propriedade como true.

    smb.HttpGetEnabled = true;
    
    smb.HttpGetEnabled = True
    
  5. O ServiceMetadataBehavior contém uma MetadataExporter propriedade. O MetadataExporter contém uma PolicyVersion propriedade. Defina o PolicyVersion valor da propriedade como Policy15. A PolicyVersion propriedade 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 que estão em conformidade com o WS-Policy 1.2.

    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
    
    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
    
  6. Adicione a ServiceMetadataBehavior instância à 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(), "")
    

    Nota

    Se você não adicionar nenhum ponto de extremidade ao serviço, o tempo de execução adicionará pontos de extremidade padrão para você. Neste exemplo, como o serviço tem um ServiceMetadataBehavior conjunto como true, o serviço tem 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. Compile e execute a aplicação da consola.

  11. Navegue até o endereço base do serviço (http://localhost:8001/MetadataSample neste exemplo) e verifique se a publicação de metadados está ativada. Você verá uma página da Web exibida que diz "Serviço simples" na parte superior e imediatamente abaixo de "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 este 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

Consulte também