Поделиться через


Как опубликовать метаданные для службы с использованием кода

Это один из двух разделов инструкций, в которых рассматривается публикация метаданных для службы Windows Communication Foundation (WCF). Существуют два способа указать, как служба должна публиковать метаданные: с помощью файла конфигурации и с помощью кода. В этом разделе показано, как публиковать метаданные для службы с помощью кода.

Aa738489.Caution(ru-ru,VS.100).gifВнимание!
В этом разделе показано, как опубликовать метаданные незащищенным образом. Любой клиент может получить метаданные из службы. Сведения о защищенной публикации метаданных службы см. в разделе Пользовательская конечная точка защищенных метаданных.

Дополнительные сведения о публикации метаданных в файле конфигурации см. в разделе Практическое руководство. Публикация метаданных для службы с использованием файла конфигурации. Публикация метаданных позволяет клиентам извлекать метаданные с помощью запроса WS-Transfer GET или запроса HTTP/GET, используя строку запроса ?wsdl. Чтобы быть уверенным, что код работает, необходимо создать базовую службу WCF. Базовая резидентная служба представлена в следующем коде.

Imports System
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
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;
        }
    }

Публикация метаданных в коде

  1. В главном методе консольного приложения создайте экземпляр объекта ServiceHost, передав тип и базовый адрес службы.

    Dim svcHost As New ServiceHost(GetType(SimpleService), New Uri("https://localhost:8001/MetadataSample"))
    
    ServiceHost svcHost = new ServiceHost(typeof(SimpleService), new Uri("https://localhost:8001/MetadataSample"));
    
  2. Создайте блок try сразу же после кода для шага 1, который перехватывает любые исключения, возникающие во время работы службы.

    Try
    
    try
    {
    
    Catch commProblem As CommunicationException
    
        Console.WriteLine("There was a communication problem. " + commProblem.Message)
        Console.Read()
    End Try
    
    }
    catch (CommunicationException commProblem)
    {
        Console.WriteLine("There was a communication problem. " + commProblem.Message);
        Console.Read();
    }
    
  3. Проверьте, не содержит ли основное приложение службы ServiceMetadataBehavior; если не содержит, создайте новый экземпляр 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
    
    // 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();
    
  4. Задайте для свойства HttpGetEnabled значение true.

    smb.HttpGetEnabled = True
    
    smb.HttpGetEnabled = true;
    
  5. ServiceMetadataBehavior содержит свойство MetadataExporter. MetadataExporter содержит свойство PolicyVersion. Задайте для свойства PolicyVersion значение Policy15. Свойству PolicyVersion можно также присвоить значение Policy12. Если задано значение Policy15, модуль экспорта метаданных вместе с метаданными создает данные о политике, соответствующие спецификации WS-Policy 1.5. Если задано значение Policy12, модуль экспорта метаданных формирует информацию о политике, соответствующую спецификации WS-Policy 1.2.

    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
    
    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
    
  6. Добавьте экземпляр ServiceMetadataBehavior в коллекцию поведений основного приложения службы.

    svcHost.Description.Behaviors.Add(smb)
    
    svcHost.Description.Behaviors.Add(smb);
    
  7. Добавьте конечную точку обмена метаданными в основное приложение службы.

    'Add MEX endpoint
    svcHost.AddServiceEndpoint( _
          ServiceMetadataBehavior.MexContractName, _
          MetadataExchangeBindings.CreateMexHttpBinding(), _
          "mex")
    
    // Add MEX endpoint
    svcHost.AddServiceEndpoint(
      ServiceMetadataBehavior.MexContractName,
      MetadataExchangeBindings.CreateMexHttpBinding(),
      "mex"
    );
    
  8. Добавьте конечную точку приложения в основное приложение службы.

    'Add application endpoint
    svcHost.AddServiceEndpoint(GetType(ISimpleService), New WSHttpBinding(), "")
    
    // Add application endpoint
    svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
    
    Aa738489.note(ru-ru,VS.100).gifПримечание
    Если в службу не добавлена ни одна конечная точка, то среда выполнения добавляет конечные точки по умолчанию. В этом примере, поскольку в службе параметр ServiceMetadataBehavior установлен в значение true, в ней также включена публикация метаданных. Дополнительные сведения о конечных точках по умолчанию см. в разделах Упрощенная конфигурация и Упрощенная конфигурация служб WCF.

  9. Откройте основное приложение службы и ожидайте входящие сообщения. Когда пользователь нажмет клавишу ВВОД, закройте основное приложение службы.

    '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. Постройте и запустите консольное приложение.

  11. В программе Internet Explorer перейдите по базовому адресу службы (в данном образце https://localhost:8001/MetadataSample) и убедитесь, что публикация метаданных включена. Вверху веб-страницы должен отображаться заголовок «Простая служба», а сразу под ним — текст «Вы создали службу». В противном случае вверху страницы отображается сообщение «Публикация метаданных для этой службы в настоящее время отключена».

Пример

В следующем примере кода показана реализация базовой службы WCF, публикующей метаданные для службы в коде.

Imports System
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("https://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
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("https://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();
            }
        }
    }
}

См. также

Задачи

Как разместить службу WCF в управляемом приложении
Резидентное размещение
Практическое руководство. Публикация метаданных для службы с использованием файла конфигурации

Основные понятия

Общие сведения об архитектуре метаданных
Использование метаданных