教程:承载和运行基本的 Windows Communication Foundation 服务

本教程介绍创建基本 Windows Communication Foundation (WCF) 应用程序所要完成的五个任务中的第三个任务。 有关教程概述,请参阅教程:Windows Communication Foundation 应用程序入门

创建 WCF 应用程序所要完成的下一个任务是在控制台应用程序中承载一个 WCF 服务。 WCF 服务公开一个或多个终结点,其中的每个终结点公开一项或多项服务操作。 服务终结点指定以下信息:

  • 一个地址,可在其中找到服务。
  • 一个绑定,其中包含用于描述客户端必须如何与服务通信的信息。
  • 一个协定,用于定义服务向其客户端提供的功能。

本教程介绍如何执行下列操作:

  • 创建并配置用于承载 WCF 服务的控制台应用项目。
  • 添加代码以承载 WCF 服务。
  • 更新配置文件。
  • 启动 WCF 服务并验证它是否正在运行。

创建并配置用于承载服务的控制台应用项目

  1. 在 Visual Studio 中创建一个控制台应用项目:

    1. 在“文件”菜单中,选择“打开”>“项目/解决方案”,然后浏览到先前创建的 GettingStarted 解决方案 (GettingStarted.sln)。 选择“打开” 。

    2. 从“视图”菜单中选择“解决方案资源管理器”。

    3. 在“解决方案资源管理器”窗口中,选择“GettingStarted”解决方案(顶部节点),然后从快捷菜单中选择“添加”>“新建项目”。

    4. 在左侧的“添加新项目”窗口中,选择“Visual C#”或“Visual Basic”下的“Windows 桌面”类别。

    5. 选择“控制台应用(.NET Framework)”模板,然后输入“GettingStartedHost”作为名称。 选择“确定”。

  2. 将“GettingStartedHost”项目中的引用添加到“GettingStartedLib”项目:

    1. 在“解决方案资源管理器”窗口中,选择“GettingStartedHost”项目下的“References”文件夹,然后从快捷菜单中选择“添加引用”。

    2. 在“添加引用”对话框中,在窗口左侧的“项目”下选择“解决方案”。

    3. 在窗口的中间部分选择“GettingStartedLib”,然后选择“确定”。

      此操作将使“GettingStartedLib”项目中定义的类型可用于“GettingStartedHost”项目。

  3. 将“GettingStartedHost”项目中的引用添加到 System.ServiceModel 程序集:

    1. 在“解决方案资源管理器”窗口中,选择“GettingStartedHost”项目下的“References”文件夹,然后从快捷菜单中选择“添加引用”。

    2. 在“添加引用”窗口中左侧的“程序集”下,选择“框架”。

    3. 依次选择“System.ServiceModel”、“确定”。

    4. 选择“文件”>“全部保存”以保存解决方案。

添加代码以承载服务

若要承载服务,请添加代码以执行以下步骤:

  1. 为基址创建一个 URI。
  2. 创建一个用于承载服务的类实例。
  3. 创建服务终结点。
  4. 启用元数据交换。
  5. 打开服务主机以侦听传入的消息。

对代码进行以下更改:

  1. 打开“GettingStartedHost”项目中的“Program.cs”或“Module1.vb”文件,将其代码替换为以下代码:

    using System;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using GettingStartedLib;
    
    namespace GettingStartedHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Step 1: Create a URI to serve as the base address.
                Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");
    
                // Step 2: Create a ServiceHost instance.
                ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
    
                try
                {
                    // Step 3: Add a service endpoint.
                    selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService");
    
                    // Step 4: Enable metadata exchange.
                    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                    smb.HttpGetEnabled = true;
                    selfHost.Description.Behaviors.Add(smb);
    
                    // Step 5: Start the service.
                    selfHost.Open();
                    Console.WriteLine("The service is ready.");
    
                    // Close the ServiceHost to stop the service.
                    Console.WriteLine("Press <Enter> to terminate the service.");
                    Console.WriteLine();
                    Console.ReadLine();
                    selfHost.Close();
                }
                catch (CommunicationException ce)
                {
                    Console.WriteLine("An exception occurred: {0}", ce.Message);
                    selfHost.Abort();
                }
            }
        }
    }
    
    Imports System.ServiceModel
    Imports System.ServiceModel.Description
    Imports GettingStartedLib.GettingStartedLib
    
    Module Service
    
        Class Program
            Shared Sub Main()
                ' Step 1: Create a URI to serve as the base address.
                Dim baseAddress As New Uri("http://localhost:8000/GettingStarted/")
    
                ' Step 2: Create a ServiceHost instance.
                Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)
               Try
    
                    ' Step 3: Add a service endpoint.
                    selfHost.AddServiceEndpoint( _
                        GetType(ICalculator), _
                        New WSHttpBinding(), _
                        "CalculatorService")
    
                    ' Step 4: Enable metadata exchange.
                    Dim smb As New ServiceMetadataBehavior()
                    smb.HttpGetEnabled = True
                    selfHost.Description.Behaviors.Add(smb)
    
                    ' Step 5: Start the service.
                    selfHost.Open()
                    Console.WriteLine("The service is ready.")
    
                    ' Close the ServiceHost to stop the service.
                    Console.WriteLine("Press <Enter> to terminate the service.")
                    Console.WriteLine()
                    Console.ReadLine()
                    selfHost.Close()
    
                Catch ce As CommunicationException
                    Console.WriteLine("An exception occurred: {0}", ce.Message)
                    selfHost.Abort()
                End Try
            End Sub
        End Class
    
    End Module
    

    有关此代码的工作原理的信息,请参阅服务承载程序步骤

  2. 更新项目属性:

    1. 在“解决方案资源管理器”窗口中选择“GettingStartedHost”文件夹,然后从快捷菜单中选择“属性”。

    2. 在“GettingStartedHost”属性页上,选择“应用程序”选项卡:

      • 对于 C# 项目,请从“启动对象”列表中选择“GettingStartedHost.Program”。

      • 对于 Visual Basic 项目,请从“启动对象”列表中选择“Service.Program”。

    3. 在“文件”菜单中选择“全部保存”。

验证服务是否正常运行

  1. 生成解决方案,然后在 Visual Studio 中运行“GettingStartedHost”控制台应用程序。

    必须以管理员特权运行该服务。 由于 Visual Studio 是以管理员特权打开的,因此在 Visual Studio 中运行“GettingStartedHost”时,应用程序也将以管理员特权运行。 或者,可以管理员身份打开一个新的命令提示符(从快捷菜单中选择“更多”>“以管理员身份运行”)并在其中运行“GettingStartedHost.exe”。

  2. 打开 Web 浏览器并通过 http://localhost:8000/GettingStarted/ 浏览到服务的页面。

    备注

    此类服务需要拥有适当的权限,以便能够在计算机上注册 HTTP 地址以进行侦听。 管理员帐户具有此权限,但对于非管理员帐户来说,必须授予对 HTTP 命名空间的权限。 有关如何配置命名空间预留的详细信息,请参阅配置 HTTP 和 HTTPS

服务承载程序步骤

下面介绍了你添加的用于承载服务的代码中的步骤:

  • 步骤 1:创建 Uri 类的实例来保存服务的基址。 包含基址的 URL 具有一个用于标识服务的可选 URI。 基址的格式如下:<transport>://<machine-name or domain><:optional port #>/<optional URI segment>。 计算器服务的基址使用 HTTP 传输、localhost、端口 8000 和 URI 段 GettingStarted。

  • 步骤 2:创建 ServiceHost 类的实例用于承载服务。 构造函数采用两个参数:实现服务协定的类的类型,以及服务的基址。

  • 步骤 3:创建 ServiceEndpoint 实例。 服务终结点由地址、绑定和服务协定组成。 ServiceEndpoint 构造函数由服务协定接口类型、绑定和地址构成。 服务协定是在服务类型中定义和实现的 ICalculator。 此示例中的绑定是 WSHttpBinding,它是一个内置绑定,将连接到符合 WS-* 规范的终结点。 有关 WCF 绑定的详细信息,请参阅 WCF 绑定概述。 将地址追加到基址以标识终结点。 代码将地址指定为 CalculatorService,将终结点的完全限定地址指定为 http://localhost:8000/GettingStarted/CalculatorService

    重要

    对于 .NET Framework 4 和更高版本,添加服务终结点是可选操作。 对于这些版本,如果你未添加代码或配置,WCF 将为服务实现的基址和协定的每种组合添加一个默认终结点。 有关默认终结点的详细信息,请参阅指定终结点地址。 有关默认终结点、绑定和行为的详细信息,请参阅简化的配置WCF 服务的简化配置

  • 步骤 4:启用元数据交换。 客户端使用元数据交换来生成用于调用服务操作的代理。 若要启用元数据交换,请创建一个 ServiceMetadataBehavior 实例,将其 HttpGetEnabled 属性设置为 true,并将 ServiceMetadataBehavior 对象添加到 ServiceHost 实例的 Behaviors 集合。

  • 步骤 5:打开 ServiceHost 以侦听传入的消息。 应用程序等待你按 Enter 键。 在应用程序实例化 ServiceHost 后,它将执行一个 try/catch 块。 有关安全捕获 ServiceHost 引发的异常的详细信息,请参阅使用 Close 和 Abort 释放 WCF 客户端资源

重要

添加 WCF 服务库时,如果你通过启动服务主机对其进行调试,Visual Studio 将为你承载该库。 为了避免冲突,可以阻止 Visual Studio 承载 WCF 服务库。

  1. 在“解决方案资源管理器”中选择“GettingStartedLib”项目,然后从快捷菜单中选择“属性”。
  2. 选择“WCF 选项”,并取消选中“调试同一解决方案中的另一个项目时启动 WCF 服务主机”。

后续步骤

在本教程中,你了解了如何执行以下操作:

  • 创建并配置用于承载 WCF 服务的控制台应用项目。
  • 添加代码以承载 WCF 服务。
  • 更新配置文件。
  • 启动 WCF 服务并验证它是否正在运行。

请继续学习下一篇教程,了解如何创建 WCF 客户端。