Практическое руководство. Публикация метаданных для службы с использованием кода
Это один из двух разделов, которые обсуждают публикацию метаданных для службы Windows Communication Foundation (WCF). Существуют два способа указать, как служба должна публиковать метаданные: с помощью файла конфигурации и с помощью кода. В этом разделе показано, как публиковать метаданные для службы с помощью кода.
Внимание
В этом разделе показано, как опубликовать метаданные незащищенным образом. Любой клиент может получить метаданные из службы. Если требуется защита данных при публикации метаданных службой, См. конечную точку настраиваемых безопасных метаданных.
Дополнительные сведения о публикации метаданных в файле конфигурации см. в разделе "Практическое руководство. Публикация метаданных для службы с помощью файла конфигурации". Публикация метаданных позволяет клиентам извлекать метаданные с помощью запроса WS-Transfer GET или запроса HTTP/GET, используя строку запроса ?wsdl
. Чтобы быть уверенным, что код работает, необходимо создать базовую службу WCF. Базовая резидентная служба представлена в следующем коде.
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
Публикация метаданных в коде
В главном методе консольного приложения создайте экземпляр объекта ServiceHost, передав тип и базовый адрес службы.
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"))
Создайте блок try сразу же после кода для шага 1, который перехватывает любые исключения, возникающие во время работы службы.
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
Проверьте, не содержит ли ведущее приложение службы ServiceMetadataBehavior; если не содержит, создайте новый экземпляр 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
Задайте свойству HttpGetEnabled значение
true.
smb.HttpGetEnabled = true;
smb.HttpGetEnabled = True
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
Добавьте экземпляр ServiceMetadataBehavior в коллекцию поведений ведущего приложения службы.
svcHost.Description.Behaviors.Add(smb);
svcHost.Description.Behaviors.Add(smb)
Добавьте конечную точку обмена метаданными в ведущее приложение службы.
// Add MEX endpoint svcHost.AddServiceEndpoint( ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex" );
'Add MEX endpoint svcHost.AddServiceEndpoint( _ ServiceMetadataBehavior.MexContractName, _ MetadataExchangeBindings.CreateMexHttpBinding(), _ "mex")
Добавьте конечную точку приложения в ведущее приложение службы.
// Add application endpoint svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
'Add application endpoint svcHost.AddServiceEndpoint(GetType(ISimpleService), New WSHttpBinding(), "")
Примечание.
Если в службу не добавлена ни одна конечная точка, то среда выполнения добавляет конечные точки по умолчанию. В этом примере, поскольку параметр ServiceMetadataBehavior установлен в значение
true
, для службы включена публикация метаданных. Дополнительные сведения о конечных точках по умолчанию см. в разделе "Упрощенная конфигурация" и "Упрощенная конфигурация" для служб WCF.Откройте ведущее приложение службы и ожидайте входящие сообщения. Когда пользователь нажмет клавишу ВВОД, закройте ведущее приложение службы.
// 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()
Создайте и запустите консольное приложение.
Перейдите к базовому адресу службы (
http://localhost:8001/MetadataSample
в этом примере) и убедитесь, что публикация метаданных включена. Вы увидите веб-страницу, которая говорит "Простая служба" в верхней части и сразу же ниже "Вы создали службу". В противном случае сообщение в верхней части итоговой страницы отображается сообщение "Публикация метаданных для этой службы в настоящее время отключена".
Пример
В следующем примере кода показана реализация базовой службы WCF, которая публикует метаданные для службы в коде.
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