如何:使用代码发布服务的元数据
这是讨论发布 Windows Communication Foundation (WCF) 服务的元数据的两个帮助主题之一。有两种方式可以指定服务应如何发布元数据:使用配置文件和使用代码。本主题演示如何使用代码发布服务的元数据。
警告: |
---|
本主题演示如何以不安全的方式发布元数据。任何客户端都可以检索服务的元数据。如果您要求服务以安全的方式发布元数据,请参见自定义安全元数据终结点。 |
有关在配置文件中发布元数据的更多信息,请参见如何:使用配置文件发布服务的元数据。通过发布元数据,客户端可以使用 WS-Transfer GET 请求或使用 ?wsdl 查询字符串的 HTTP/GET 来检索元数据。若要确保代码能够工作,必须创建一个基本的 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;
}
}
在代码中发布元数据
在控制台应用程序的主方法中,通过传入服务类型和基址来实例化 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"));
紧接在步骤 1 的代码下面创建一个 try 块,这将捕获在服务运行过程中引发的任何异常。
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(); }
检查服务主机是否已经包含一个 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();
将 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(GetType(ISimpleService), New WSHttpBinding(), "")
// Add application endpoint svcHost.AddServiceEndpoint(typeof(ISimpleService), new WSHttpBinding(), "");
注意: 如果不希望向服务添加任何终结点,则运行时为您添加默认终结点。在此示例中,由于服务的 ServiceMetadataBehavior 设置为 true,因此服务还启用了发布元数据。有关默认终结点的更多信息,请参见简化配置和 WCF 服务的简化配置。 打开服务主机并等待传入调用。当用户按 Enter 时,关闭服务主机。
'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();
生成并运行控制台应用程序。
使用 Internet Explorer 浏览服务的基址(本示例中的 https://localhost:8001/MetadataSample)并验证是否已打开元数据发布。您应会看到一个网页,该网页顶部显示“Simple Service”(简单服务),其下面紧接着显示“You have created a service”(已经创建服务)。如果未显示上述内容,则结果页顶部会显示消息:“Metadata publishing for this service is currently disabled”(当前禁用服务的元数据发布)。
示例
下面的代码示例演示如何在代码中实现发布服务的元数据的基本 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 服务
自承载
如何:使用配置文件发布服务的元数据