65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Communication Foundation (WCF) 概述

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.78/5 (111投票s)

2008年9月10日

CPOL

8分钟阅读

viewsIcon

382937

downloadIcon

5091

本文介绍了 Windows Communication Foundation (WCF) 以及如何在应用程序中使用它。它描述了 WCF 模型,是面向初学者的快速入门指南。

引言

Windows Communication Foundation (WCF) 是 .NET 框架的扩展,用于构建和运行互联系统。Windows Communication Foundation 提供了一个统一的框架,用于构建安全可靠的事务性 Web 服务。Windows Communication Foundation 结合并扩展了分布式系统、Microsoft .NET Remoting、Web 服务和 Web 服务增强 (WSE) 的功能,以开发和交付统一的安全系统。WCF 框架基于面向服务的体系结构构建松散耦合的应用程序,该体系结构可以更安全、更可靠地跨平台进行互操作。

WCF 通过整合各种技术,简化了面向服务的应用程序的开发工作,从而提高了开发效率。此外,它通过统一企业服务、消息传递、.NET Remoting、Web 服务和 WSE 来降低应用程序的复杂性。WCF 使用属性编程模型构建应用程序,从而提高了开发人员的生产力。WCF 作为 .NET 3.0 运行时组件的一部分引入。Windows Communication Foundation 提供了一个面向服务的编程模型,用于构建跨组织和平台边界的面向服务的应用程序。它支持广泛的 Web 服务标准,如 XML、XSD、SOAP、XPath、WSDL,以及 WS-Addressing、WS-Policy、WS-Security、WS-Trust、WS-Secure Conversation、WS-Reliable Messaging、WS-Atomic Transaction、WS-Coordination 和 WS-Policy 等高级标准和规范。下图描绘了 Windows Communication Foundation (WCF) 框架模型。

WCF 通信模型

Windows Communication Foundation (WCF) 遵循客户端-服务器模型来建立应用程序之间的通信。客户端应用程序可以通过服务公开的终结点直接访问服务。终结点只不过是定义的访问位置,消息可以通过这些位置发送或接收,而一个服务可以拥有多个终结点。

WCF 服务由以下主要组件组成。下图显示了这些组件之间的关系。

  • 服务合同
  • 操作协定
  • 数据合同
  • 数据成员

服务合同

服务协定是指定对话中消息方向和类型的协定。它是一个接口或类,用于在 Windows Communication Foundation (WCF) 应用程序中定义服务协定。服务协定是外部应用程序使用服务功能的入口点,并且服务中至少应有一个服务协定。服务协定定义如下:

// Student ServiceContract
[ServiceContract]
public interface IStudentService
{
    // Define the OperationContact here….
}

接口的 ServiceContract 属性定义了服务接口中的服务协定。服务协定定义了服务中可用的操作,这些操作类似于 Web 服务中的 Web 服务方法。IstudentService 是一个学生服务接口,它向外部系统公开此服务中的所有操作协定或方法。

操作协定

操作协定定义了外部系统可访问的服务的方法。所有这些方法都需要应用 OperationContract 属性,这些方法也类似于 Web 服务中的 Web 方法。操作协定定义如下:

// Student ServiceContract
[ServiceContract]
public interface IStudentService
{
      // Define the GetStudentFullName OperationContact here….
    [OperationContract]
    String GetStudentFullName (int studentId);

      // Define the GetStudentInfo OperationContact here….
    [OperationContract]
    StudentInformation GetStudentInfo (int studentId);

}

数据合同

数据协定定义了一个类型,该类型包含一组数据成员或字段,这些成员或字段将作为复合类型在服务协定中使用。它是一个松散耦合的模型,该模型在服务实现外部定义,并可被其他平台上的服务访问。要定义数据协定,请将 DataContract 属性应用于类,以便由序列化器序列化该类,并将 DataMember 属性应用于类中必须序列化的字段。可以定义如下的 StudentInformation 数据协定:

[DataContract]
public class StudentInformation
{
    // Define the Datamembers here….
}

数据成员

数据成员指定了作为数据协定一部分的类型,用作协定的复合类型成员。要定义数据成员,请将 DataMember 属性应用于必须序列化的字段。DataMember 属性可以应用于私有属性,但它们仍会被序列化和反序列化,并且用户或进程可以访问它们。以下代码显示了如何在数据协定中定义数据成员:

[DataContract]
public class StudentInformation
{
      _studentId = studId;

    [DataMember]
    public int StudentId
    {
        get { return _studentId; }
        set { _studentId = value; }
    }

}

使用 Visual Studio 2008 创建 WCF 应用程序

以下是使用 Visual Studio 2008 创建 WCF 应用程序所需的步骤:

  1. 打开 Visual Studio 2008。
  2. 在“文件”菜单中,单击“新建项目”。
  3. 在“项目类型”树中,展开“Visual C#”节点,然后选择“Web”节点。
  4. 选择“WCF 服务应用程序”。
  5. 选择要保存应用程序的文件夹,然后单击“确定”按钮。
  6. 该项目将使用默认文件创建,这些文件是 IService1.csService1.svcService1.svc.csweb.config

您可以看到带有 IService1ServiceContract 属性,并且使用 OperationContract 属性定义了公开的方法。Service1 是实现 IService1 的具体类。终结点和其他行为属性在 Web.Config 文件的 system.serviceModel 部分中定义。

如果您重命名了服务,则需要对 Web.Config 的上述部分进行必要的更改,否则外部系统将无法识别这些服务。

自定义默认 WCF 服务

现在,我们需要根据我们的需求对默认 WCF 应用程序进行必要的更改。第一步是重命名现有的服务文件,或者删除现有的文件并创建新的文件。在本例中,我将采用第一种方法,重命名现有的文件。

将项目重命名为 WcfStudentService,将文件 Iservice1.cs 重命名为 IstudentService.cs,将 Service.svc 重命名为 StudentService.svc。请注意,代码文件 Service.svc.cs 也将被重命名为 Service.svc.cs。在 Web.Config 文件中进行相应的更改。

删除 IstudentService 中的现有代码,并添加以下代码。OperationContract 属性应应用于可由外部系统访问的方法。DataContract 应应用于 StudentInformation 类,并且 StudentInformation 中的字段应使用 DataMember 属性进行标记,因为 StudentInformationIstudentService 中用作复合类型。

namespace WcfStudentService
{
    // Defines IStudentService here
    [ServiceContract ]
    public interface IStudentService
    {
        // Define the GetStudentFullName OperationContact here….
        [OperationContract]
        String GetStudentFullName(int studentId);

        // Define the GetStudentInfo OperationContact here….
        [OperationContract]
        IEnumerable<studentinformation> GetStudentInfo(int studentId);
    }


    // Use a data contract as illustrated in the sample below to add
    // composite types to service operations.
    [DataContract]
    public class StudentInformation
    {
        int _studentId ;
        string _lastName;
        string _firstName;

        public StudentInformation(int studId, string firstname, string lastName)
        {
            _studentId = studId;
            _lastName = lastName;
            _firstName = firstname;
        }

        [DataMember]
        public int StudentId
        {
            get { return _studentId; }
            set { _studentId = value; }
        }

        [DataMember]
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }

        [DataMember]
        public string LastName
        {
            get { return _lastName; }
            set { _lastName = value; }
        }
    }
}

请注意,StudentInformation 是一个独立的类,并且由于声明为 public,因此可以被外部系统访问。

StudentService 是实现了 IstudentService 的具体类。在服务类中添加以下代码:

namespace WcfStudentService
{
    // StudentService is the concrete implmentation of IStudentService.
    public class StudentService : IStudentService
    {

        List<studentinformation> Students = new List<studentinformation>() ;

        // Create  list of students
        public StudentService()
        {
            Students.Add(new StudentInformation(1001, "Nikhil",
                "Vinod"));
            Students.Add(new StudentInformation(1002, "Joshua",
                "Hunter"));
            Students.Add(new StudentInformation(1003, "David",
                "Sam"));
        }

        // Method returning the Full name of the student for the studentId
        public string GetStudentFullName(int studentId)
        {
            IEnumerable<string> Student
                         = from student in Students
                           where student.StudentId == studentId
                           select student.FirstName + " " + student.LastName;

            return Student.Count() != 0 ? Student.First() : string.Empty;
        }

        // Method returning the details of the student for the studentId
        public IEnumerable<studentinformation> GetStudentInfo(int studentId)
        {

            IEnumerable<studentinformation> Student =  from student in Students
                                   where student.StudentId == studentId
                                   select student ;
            return Student;
        }
    }

托管和测试 WCF 服务

WCF 服务可以在 Internet Information Service (IIS) 和 Windows Activation Service (WAS)(随 Vista 和 IIS 7.0 一起提供)中托管。在本例中,使用 IIS 托管 WCF 服务。构建服务项目,然后按 F5 运行以从 Visual Studio 2008 运行。默认情况下,它将 IIS 作为托管服务。您可以从浏览器窗口中显示的文件列表中选择 StudentService.svc 文件,然后将显示如下页面:

与 Web 服务一样,您无法在没有客户端的情况下直接测试 WCF 服务。

Microsoft 提供了一个易于测试服务的接口,即 WcfTestClient 实用工具。如果服务由 WCF 服务主机 (WcfSvcHost.exe) 从 Visual Studio 托管,则会打开 WcfTestClient 窗口,或者您可以从命令提示符明确运行 WcfTestClient 实用工具。您可以按以下方式运行它:

C :\> WcfTestClient https://:4489/StudentService.svc

https://:4489/StudentService.svc 应该是要测试的服务的名称。WcfTestClient 在左侧窗格中显示服务及其公开的方法;它还提供了在右上角窗格中输入参数值的选项。当您在参数框中输入值并单击“调用”按钮时,它会在该实用工具的右下角窗格中显示结果。

消费 WCF 服务

可以通过 WCF 客户端从客户端应用程序与 WCF 服务进行通信。使用 WCF 服务的第一步是创建 WCF 客户端和相关的配置文件。ServiceModel 元数据实用工具 (Svcutil.exe) 是一个命令行工具,其选项之一是创建 WCF 客户端。另一个选项是通过在 Windows 项目中添加服务引用来创建 WCF 客户端。本示例使用第二个选项创建 WCF 客户端。

此外,添加一个具有 ButtonLabelTextBoxDataGridView 的 Windows 应用程序窗体,用于显示学生信息。

创建 WCF 客户端

要将服务引用添加到 Windows 应用程序,请执行以下步骤:

  1. 打开解决方案资源管理器。
  2. 右键单击 Windows 应用程序的“引用”,或右键单击“服务引用”并选择“添加服务引用”。
  3. 将弹出“添加服务引用”窗口。
  4. 单击“发现”,然后在“发现”下拉列表中选择“解决方案中的服务”。
  5. 它将搜索并显示解决方案中的服务,如下所示:
  6. 将命名空间重命名为 StudentServiceReference,选择 StudentService,然后单击“确定”按钮。
  7. 代理已创建并添加到服务引用中,可以开始使用 StudentService 引用在应用程序中使用该服务。

使用 WCF 客户端

创建 WCF 客户端实例以与服务通信。以下行创建了服务客户端代理:

// create the proxy to access the service
StudentServiceClient studClient = 
  new StudentServiceClient("WSHttpBinding_IStudentService");

StudentServiceClient 是添加服务引用到项目时生成的 WCF 客户端类。WSHttpBinding 是服务 web.config 文件中指定的终结点绑定方法,而 IStudentService 是要通信的服务。

创建代理或 WCF 客户端实例后,可以像在早期版本的 .NET 中访问 Web 服务方法一样访问服务的方法。可以如下调用服务的方法 GetStudentFullNameGetStudentInfo

// Get Fullname of the Student through the proxy from service
lblFullName.Text = studClient.GetStudentFullName(
                     Convert.ToInt16(textBox1.Text));

// Get details of the Student through the proxy from service
IEnumerable<studentinformation> x = 
   studClient.GetStudentInfo(Convert.ToInt16(textBox1.Text));
dataGridView1.DataSource = x;

在窗体中,如果您输入学生 ID 并单击“显示学生信息”按钮,您将调用服务方法,并使用详细信息填充 Fullname 标签和 DataGridView

结论

这只是对 Windows Communication Foundation 框架的初步介绍。我将在下一篇文章中详细介绍如何为不同类型的通信配置服务和客户端。

参考

© . All rights reserved.