如何:在托管应用程序中承载 WCF 服务
若要在托管应用程序中承载某项服务,请在托管应用程序代码内嵌入该服务的代码,在代码中强制定义、通过配置以声明的方式定义或者使用默认终结点定义该服务的终结点,然后创建 ServiceHost 的实例。
若要开始接收消息,请调用 ServiceHost 上的 Open。这样即可创建并打开服务的侦听器。以这种方式承载服务的做法通常称为“自承载”,原因是托管的应用程序会自己处理承载工作。若要关闭服务,请调用 ServiceHost 上的 System.ServiceModel.Channels.CommunicationObject.Close。
在托管的 Windows 服务中、在 Internet 信息服务 (IIS) 中或在 Windows 进程激活服务 (WAS) 中也可以承载服务。有关服务的承载选项的更多信息,请参见承载服务。
在托管应用程序中承载服务是一个非常灵活的选项,因为这种做法在部署时所需的基础结构最少。有关在托管应用程序中承载服务的更多信息,请参见在托管应用程序中承载。
下面的过程演示如何在控制台应用程序中实现自承载的服务。
创建自承载服务
打开 Visual Studio 2010,然后在**“文件”菜单中依次选择“新建”和“项目…”**。
在**“已安装的模板”列表中,依次选择“Visual C#”和“Windows”或依次选择“Visual Basic”和“Windows”。根据您的 Visual Studio 2010 设置,“已安装的模板”列表中的“其他语言”**节点下可能会显示其中一种语言或者同时显示这两种语言。
从**“Windows”列表中选择“控制台应用程序”。在“名称”框中键入
SelfHost
,然后单击“确定”**。在**“解决方案资源管理器”中右击“SelfHost”,然后选择“添加引用…”。从“.NET”选项卡中选择“System.ServiceModel”,然后单击“确定”**。
提示: 如果“解决方案资源管理器”窗口不可见,请从“视图”菜单中选择“解决方案资源管理器”。 如果文件尚未打开,请在**“解决方案资源管理器”中双击“Program.cs”或“Module1.vb”**,以在代码窗口中打开它。将下面的语句添加到文件的顶部。
Imports System.ServiceModel Imports System.ServiceModel.Description
using System.ServiceModel; using System.ServiceModel.Description;
定义和实现服务协定。此示例定义了一个
HelloWorldService
,它基于对服务的输入返回消息。<ServiceContract()> Public Interface IHelloWorldService <OperationContract()> Function SayHello(ByVal name As String) As String End Interface Public Class HelloWorldService Implements IHelloWorldService Public Function SayHello(ByVal name As String) As String Implements IHelloWorldService.SayHello Return String.Format("Hello, {0}", name) End Function End Class
[ServiceContract] public interface IHelloWorldService { [OperationContract] string SayHello(string name); } public class HelloWorldService : IHelloWorldService { public string SayHello(string name) { return string.Format("Hello, {0}", name); } }
注意: 有关如何定义和实现服务接口的更多信息,请参见如何:定义 Windows Communication Foundation 服务协定和如何:实现 Windows Communication Foundation 服务协定。 在
Main
方法的顶部,使用该服务的基址创建 Uri 类的实例。Dim baseAddress As Uri = New Uri("https://localhost:8080/hello")
Uri baseAddress = new Uri("https://localhost:8080/hello");
创建 ServiceHost 类的实例,并将表示服务类型的 Type 和基址统一资源标识符 (URI) 传递到 ServiceHost。启用元数据发布,然后调用 ServiceHost 上的 Open 方法,以初始化服务并使其准备好接收消息。
' Create the ServiceHost. Using host As New ServiceHost(GetType(HelloWorldService), baseAddress) ' Enable metadata publishing. Dim smb As New ServiceMetadataBehavior() smb.HttpGetEnabled = True smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15 host.Description.Behaviors.Add(smb) ' Open the ServiceHost to start listening for messages. Since ' no endpoints are explicitly configured, the runtime will create ' one endpoint per base address for each service contract implemented ' by the service. host.Open() Console.WriteLine("The service is ready at {0}", baseAddress) Console.WriteLine("Press <Enter> to stop the service.") Console.ReadLine() ' Close the ServiceHost. host.Close() End Using
// Create the ServiceHost. using (ServiceHost host = new ServiceHost(typeof(HelloWorldService), baseAddress)) { // Enable metadata publishing. ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; host.Description.Behaviors.Add(smb); // Open the ServiceHost to start listening for messages. Since // no endpoints are explicitly configured, the runtime will create // one endpoint per base address for each service contract implemented // by the service. host.Open(); Console.WriteLine("The service is ready at {0}", baseAddress); Console.WriteLine("Press <Enter> to stop the service."); Console.ReadLine(); // Close the ServiceHost. host.Close(); }
注意: 此示例使用默认终结点,且该服务不需要任何配置文件。如果未配置任何终结点,则运行时会为该服务实现的每个服务协定的每个基地址创建一个终结点。有关默认终结点的更多信息,请参见简化配置和 WCF 服务的简化配置。 按 Ctrl+Shift+B 生成解决方案。
测试服务
按 Ctrl+F5 运行服务。
打开**“WCF 测试客户端”**。
提示: 若要打开“WCF 测试客户端”,请打开 Visual Studio 2010 命令提示符,然后执行“WcfTestClient.exe”。 从**“文件”菜单中选择“添加服务...”**。
在地址框中键入
https://localhost:8080/hello
,然后单击**“确定”**。提示: 确保服务正在运行,否则此步骤将失败。如果已经更改了代码中的基址,则在此步骤中使用修改后的基址。 双击**“我的服务项目”节点下的“SayHello”。在“请求”列表的“值”列中,键入您的姓名,然后单击“调用”。此时,“响应”**列表中将显示一条答复消息。
示例
下面的示例创建 ServiceHost 对象以承载 HelloWorldService
类型的服务,然后调用 ServiceHost 上的 Open 方法。在代码中提供基址,启用元数据发布,并使用默认终结点。
Imports System.ServiceModel
Imports System.ServiceModel.Description
Module Module1
<ServiceContract()>
Public Interface IHelloWorldService
<OperationContract()>
Function SayHello(ByVal name As String) As String
End Interface
Public Class HelloWorldService
Implements IHelloWorldService
Public Function SayHello(ByVal name As String) As String Implements IHelloWorldService.SayHello
Return String.Format("Hello, {0}", name)
End Function
End Class
Sub Main()
Dim baseAddress As Uri = New Uri("https://localhost:8080/hello")
' Create the ServiceHost.
Using host As New ServiceHost(GetType(HelloWorldService), baseAddress)
' Enable metadata publishing.
Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
host.Description.Behaviors.Add(smb)
' Open the ServiceHost to start listening for messages. Since
' no endpoints are explicitly configured, the runtime will create
' one endpoint per base address for each service contract implemented
' by the service.
host.Open()
Console.WriteLine("The service is ready at {0}", baseAddress)
Console.WriteLine("Press <Enter> to stop the service.")
Console.ReadLine()
' Close the ServiceHost.
host.Close()
End Using
End Sub
End Module
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace SelfHost
{
[ServiceContract]
public interface IHelloWorldService
{
[OperationContract]
string SayHello(string name);
}
public class HelloWorldService : IHelloWorldService
{
public string SayHello(string name)
{
return string.Format("Hello, {0}", name);
}
}
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("https://localhost:8080/hello");
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(HelloWorldService), baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// Open the ServiceHost to start listening for messages. Since
// no endpoints are explicitly configured, the runtime will create
// one endpoint per base address for each service contract implemented
// by the service.
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
}
}
}
另请参见
任务
如何:在 IIS 中承载 WCF 服务
自承载
如何:定义 Windows Communication Foundation 服务协定
如何:实现 Windows Communication Foundation 服务协定
参考
Uri
AppSettings
ConfigurationManager
概念
承载服务
ServiceModel 元数据实用工具 (Svcutil.exe)
使用绑定配置服务和客户端
系统提供的绑定