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

简单演示 WCF Web 服务

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (20投票s)

2015 年 3 月 11 日

CPOL

13分钟阅读

viewsIcon

67108

downloadIcon

2511

快速了解简单的 WCF Web 服务!

Content

  1. WCF - 简介 
  2. 什么是服务协定、操作协定和数据协定
  3. 关于 WCF 配置的说明
  4. 了解我们定义了简单业务功能的项目
  5. 通过 WCF Web Service 公开上述业务功能
  6. 使用 WCF 测试客户端测试我们新创建的 Web Service
  7. 为我们新的 Web Service 创建代理客户端
  8. 测试我们上面创建的代理客户端
  9. 最终想法

引言

WCF

在本文中,我们将介绍一个简单的 WCF Web Service。

通过示例来理解概念会更容易。

在本文中,我们将总共使用 3 个项目。
类库项目 TweetBL 将代表一个需要启用服务功能的项目。然后,我们将介绍一个 WCF 服务项目,该项目将把我们的 TweetBL 项目的业务功能公开为 Web Service。在我们的第三个也是最后一个项目中,我们将创建一个代理客户端来消耗我们的 WCF Web Service。

最后,值得一提的是,我们将逐步测试每一个细节。请坚持下去,不要慌张,我已尽量使用简单的代码,并且在这里只关注 WCF!
那么,开始吧……

WCF - 简介

WCF 代表 Windows Communication Foundation。
WCF 是一个框架,旨在支持客户端和服务器上的基于消息的通信。
WCF 支持多种传输方式,如 SOAP over HTTP(我们的示例 Web Service 基于此)、TCP、命名管道、MSMQ 等。
WCF 支持多种编码方式,如 XML、文本、二进制以及其他一些选项。
目前,为了举例说明,一些采用 WCF 的技术包括 Windows Workflow、Silverlight 等。

WCF Architecture

什么是服务协定、操作协定和数据协定

在 WCF 中,协定用于定义功能。
协定基本上是客户端和服务之间的正式协议,用于定义一种平台中立的
以及标准化方式来描述服务将要做什么以及能够做什么。

WCF 定义了 4 种类型的协定

  1. 服务契约
  2. 操作协定
  3. 数据协定
  4. 故障契约

在本文中,我们将重点介绍前三种协定。

WCF Architecture

服务协定 定义了 Web Service 的能力。
它本质上是一个接口协定,将应用程序(业务功能 - 要公开的业务操作
)绑定到提供一组固定的操作(如接口协定中所述),以供
消耗 Web Service 的源使用。
它简单地描述了在服务终结点上可用,并向外界公开的
客户端可调用的操作或方法。

就代码而言
我们所需要做的就是编写代码并使用 ServiceContract 特性装饰一个接口。
该接口将包含作为 Tweet Service 的一部分向外界提供的成员(方法)。

 //
 // Service Contract
 // Wee need to decorate the Interface with the ServiceContract Attribute
 //
 [ServiceContract]
 interface ITweetService 
 {
    // Interface members
    // Tweet Service Methods that need to be exposed to the outside world!
 }

另一方面,操作协定 定义了外部系统可以访问的服务方法。
它是上面创建的服务协定接口不可或缺的一部分。
在服务协定接口中用 Operation Contract 特性标记的成员是那些
向外部系统公开的成员。
在服务协定接口中没有用 Operation Contract 特性装饰的成员
作为 Web Service 的一部分公开。

就代码而言
它只能应用于方法。
它用于装饰属于服务协定接口的方法。

 //
 // Service Contract - Operation Contact example
 //
 [ServiceContract]
 interface ITweetService 
 {
    [OperationContract]
    int AddNewTweet(string tweetBy, string tweet);
	
    // Other members...
 }

数据协定 定义了 Web Service 操作要发送和接收的数据的类型和格式。
它是服务和客户端之间的一个正式协议,抽象地描述了要交换的数据。
数据协定可以是显式的或隐式的。像 intstring 等简单类型具有隐式数据协定。
用户定义的对象的显式或复杂类型,您必须使用 [DataContract][DataMember] 特性来定义数据协定。

下面提到了关于数据协定的一些重要因素

  1. 描述了传递到 Web Service 操作和从 Web Service 操作传递出的数据的格式、结构和类型
  2. 进行 CLR 类型和 XML Schema 之间的映射
  3. 定义相关数据如何序列化和反序列化
    序列化 = 将数据(对象)转换为可以在网络上传输的字节序列
    反序列化 = 将字节序列重新组装回其原始形式 -> 数据(对象)
  4. 是一个松耦合模型,定义在服务实现之外,并且可以被其他平台的服务访问

就代码而言
要定义数据协定,请将 DataContract 特性应用于类,以便序列化器可以序列化该类,并将 DataMember 特性应用于类中必须序列化的字段。
我们需要将 System.Runtime.Serialization 引用添加到项目中。
该程序集包含 DataContract DataMember 特性。

 //
 // Data Contract - Data Member example
 //
 // Creating a user defined data type called SampleData. This data type should be identified 
 // for serialization and de-serialization by mentioning with [DataContract] and [DataMember] attribute.
 //
 // There should be: using System.Runtime.Serialization; reference in the using section.
 //
 [DataContract]
 public class SampleData 
 {
    private string _somePropertyPrivateVariable;
	
    [DataMember]
    public string SomeProperty
    {
       get { return _somePropertyPrivateVariable;}
       set { _somePropertyPrivateVariable = value;}
    }
	
    // Other properties...
 }

关于 WCF 配置的说明

由于 WCF 支持如此多的技术、传输协议和编码方式,因此它在很大程度上依赖于配置。

所有这些都归结为以下几点

  • 终结点 (Endpoint):这是服务器发送和接收数据的地址。
  • 绑定 (Binding):它定义了终结点使用的传输和编码。
  • 行为 (Behaviour):这是最后一部分,负责 Web Service、终结点、操作和/或客户端的运行时行为。

行为很重要,因为它们会影响错误处理、凭据以及许多其他重要功能。

在本文中,我们将使用默认的 WCF 配置。这里解释了为每个项目提供的默认 WCF 配置

了解我们定义了简单业务功能的项目

我们将把这个业务功能公开为 Web Service!

我们将要公开为 Web Service 的项目是一个简单的类库项目,名为 TweetBL(BL 代表 Business Layer,业务层)。
TweetBL 项目代表已经确定要通过 Web Service 在 Web 上提供的业务代码。
TweetBL 项目具有以下业务功能(方法),将作为服务公开。

业务功能方法包括

  1. 更新推文
  2. 保存/插入推文
  3. 删除推文
  4. 按 ID 检索推文,以及
  5. 检索所有推文

TweetBL 项目

TweetBL Project Screen-shot

Tweet.cs 只是一个数据类,其中包含我们要获取/更新/插入和删除以管理推文的所有数据成员。可以将其视为模型(数据模型)。

Tweet.cs Class Screen-shot

TweetService.cs 是包含业务方法的类,这些方法对 Tweet 数据进行所有必要的处理以进行管理和维护。
注意:由于我们没有使用实际数据库,因此还有一些辅助代码(与要公开的业务功能无关),以保持事物相对简单。

TweetService.cs Class Screen-shot

通过 WCF Web Service 公开上述业务功能

在我们快速浏览了 TweetBL 项目后,是时候开始编写真正的代码了……
让我们通过添加一个名为 Tweet.WebService 的新项目开始 - 这将是我们的 WCF 项目。

Adding Tweet.WebService Project Screen-shot

Tweet.WebService Project added Screen-shot

现在,我们将向 Tweet.WebService 项目添加一个 WCF 服务。
转到添加新项(在 Tweet.WebService 项目上),然后按照下面的屏幕截图操作

Tweet.WebService Adding New Item Screen-shot

添加服务后,它会使项目发生一些更改。
已添加 Serialization ServiceModal 引用以及其他一些文件!

Tweet.WebService Project Updated References Screen-shot

Web.config 文件也已修改!
需要注意的一点是,一旦我们添加了一个 WCF Web Service,Web.config 文件就会更新为基于 SOAP over HTTP 的 WCF 服务的默认配置……

Tweet.WebService Project Updated Web.Config Screen-shot

我们可以看到为我们的 WCF 服务定义了一系列行为,特别是为我们的 Web Service 定义了一个。
行为定义了我们服务的运行时方面。

您可以随意添加、删除或修改这些设置,但对于本文,我们将坚持使用默认设置。
这里遵循KISS 原则 - 保持简单,笨蛋!

以下是对所提供 WCF 配置的简要解释:

此设置允许使用 get 动词通过 HTTP 和 HTTPS 发送元数据。

 //
 // Web.Config snippet 
 // 
 <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>

我们将 includeExceptionDetailInFaults 设置为 false ,以便如果服务器上发生任何错误,我们不会将异常的详细信息发送回客户端。

	 //
 // Web.Config snippet 
 // 
 <serviceDebug includeExceptionDetailInFaults="false"/>

下面的配置设置定义了 Web Service 的托管方式。将 aspNetCompatibilityEnabled 设置为 true 使我们能够与 IIS 中的 ASP.NET 管道集成。
最后,将 multipleSiteBindingsEnabled 设置为 true 允许我们将 Web Service 与
IIS 上配置的多个站点绑定关联起来。

 //
 // Web.Config snippet 
 // 
 <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true"/>

以上所有设置都已默认设置好……所以我们不必担心任何事情!

现在,一个接口和一个 svc 文件也被添加到了项目中。让我们现在关注它们。

Tweet.WebService Project automatically added Interface Screen-Shot

WCF 使用接口来定义每个单独服务的各项能力,而ITweetService.cs 代表
该设计和目的。

 //
 // ITweetService.cs snippet 
 // 
[ServiceContract]
public interface ITweetService
{
    [OperationContract]
    void DoWork();
}

ServiceContract 特性告诉 WCF 该接口ITweetService.cs 可以作为 Web Service 的一部分用于提供数据。
OperationContract 特性简单地标识了服务可以执行的操作。

最后,我们有 TweetService.svc

 //
 // ITweetService.svc (right-click: View Markup) snippet
 // 
 <%@ ServiceHost Language="C#" Debug="true" 
 Service="Tweet.WebService.TweetService" CodeBehind="TweetService.svc.cs"%>

ServiceHost 指令(上图)是 WCF 特有的 - 它启用了我们在前几节中探索过的所有绑定和配置。

其代码隐藏文件非常简洁,因为所有 WCF 特定的配置都已被抽象出来并指定
ITweetService 接口中。

 //
 // ITweetService.svc.cs Code behind file snippet
 // 
public class TweetService : ITweetService
{
    public void DoWork()
    {
       // Lets do some work
    }
}

现在让我们将业务代码整合到这个新创建的 WCF Web Service 中

我们将从 TweetBL 项目公开所有相关的 TweetService 类方法来管理推文,作为 Web Service。
让我们开始通过 Tweet.WebService 项目的 ITweetService 接口公开这些方法。

Tweet.WebService 项目的 ITweetService 接口添加方法

Tweet.WebService Project ITweetService (Methods added) Interface Screen-Shot

现在,我们必须在 TweetService.svc.cs 类中实现 ITweetService.cs 接口。我将通过利用我们在项目中定义的业务功能代码来实现这些方法:TweetBL 项目 - TweetService.cs 类。

Project TweetBL - Class TweetService.cs Business methods Screen-Shot

TweetService.svc.cs 类中实现 ITweetService.cs 接口。

Project Tweet.WebService - Class TweetService.svc.cs implemented methods Screen-Shot

现在,在实现并生成项目后 - 转到 TweetService.svc,右键单击并选择在浏览器中查看。

Project Tweet.WebService - Class TweetService.svc.cs view in browser Screen-Shot

这将显示我们 Web Service 的生成的 HTML 页面,我们可以使用该页面来构建我们的代理客户端(消耗我们服务的客户端)。

Project Tweet.WebService - Class TweetService.svc.cs generated html page Screen-Shot

最后,我们离测试服务只有一步之遥了。让我们在数据对象 Tweet.cs (我们的 Transport 类)项目 TweetBL 上用以下特性标记

  • [DataContract]:用此特性标记我们的数据传输类 Tweet.cs TweetBL 项目)
  • [DataMember]:用此特性标记 Tweet.cs 类(TweetBL 项目)中的所有字段

Project TweetBL - Class Tweet.cs post DataContract and DataMember attributes Screen-Shot

现在我们准备测试我们的 WCF Service 了!
注意* 数据协定已在此处解释

使用 WCF 测试客户端测试我们新创建的 Web Service

在上节中,我们完成了 ITweetService.cs 接口在 TweetService.svc.cs 类中的实现。
现在是快速测试的时候了……将 Tweet.WebService 项目设置为启动项目。
选择 TweetService.svc 类,然后按 F5 启动 WCF 测试客户端。

Tweet.WebService Project - WCF Test Client Launch Screen-Shot

选择 GetTweets() 方法并双击 - 这将为我们启动一个窗体……
GetTweets() 服务方法不接受任何参数,因此我们可以直接单击“调用”按钮

Tweet.WebService Project - WCF Test Client GetTweets() Screen-Shot

上面的屏幕截图显示了 GetTweets() 服务调用的结果 - 结果显示在一个格式良好的数据表中!

它返回了 4 个元素的列表。
我们的业务层项目 TweetBL - 类 TweetService.cs 已被设置为创建 4 条初始推文。
所有这 4 条记录都已返回。

如果您单击XML 选项卡 - 您可以看到请求和响应的 SOAP 信封。
Request 信封由客户端生成,Response 信封是我们从 WCF 服务收到的。

Tweet.WebService Project - WCF Test Client XML Tab Screen-Shot

注意 - 您也可以使用 WCF 测试客户端测试所有其他服务方法。
其余的服务方法我留给您自己玩。

为我们新的 Web Service 创建代理客户端

添加一个名为 TweetClient 的新控制台应用程序项目,它将是消耗我们 Tweet Web Service 的代理客户端。

TweetClient Project - Screen-Shot

现在,让我们为 TweetClient 项目添加 TweetService 的服务引用
右键单击 TweetClient 项目,然后转到添加 -> 服务引用……

TweetClient Project - Add Service reference Screen-Shot

单击“发现”按钮 - 由于我们的服务在同一个解决方案中,它将被发现并显示。

TweetClient Project - Discover Button Screen-Shot

通过展开 TweetService,它将从服务下载 Web Service 定义文档,并获取 WCF 服务的服务协定。
正如您所见,我们在服务协定中公开的 5 个操作已显示出来。

TweetClient Project - WSDL Download Screen-Shot

单击“确定”,选定的服务引用将被添加到名为“Service References”的文件夹中。

TweetClient Project - Service reference added Screen-Shot

如果您双击新添加的服务引用,它会打开对象浏览器。
如果您选择 ITweetService 接口,这里有一些有趣的信息可以查看

TweetClient Project - double click Service reference Screen-Shot

TweetClient Project - Object Browser Screen-Shot

正如您在上图中所见 - 对于 ITweetService 接口,对象浏览器不仅显示了
我们通过服务协定公开的 5 个操作,它还显示了这些方法的异步版本。这些异步方法是默认添加的,它允许客户端创建异步 Web 请求!以便与服务器通信而不阻塞其主线程。

另外,快速看一下我们的 Tweet 传输类……
这是我们将用于与服务器进行所有调用(例如:创建获取更新)之间的数据传输的类。
它具有执行上述操作所需的所有字段。

TweetClient Project - Object Browser Tweet Transport Class Screen-Shot

最后,让我们看看 TweetServiceClient……
这是 ITweetService 的具体实现。它也有 5 个不同的构造函数定义。

注意* 默认构造函数将使用我们添加服务引用时使用的 Web 地址!
其他构造函数可用于为我们提供不同的选项来配置服务,以使用不同的服务器,例如测试服务器或生产服务器,或两者都使用。
使用这些构造函数,您可以定义服务将要通信的终结点。
在本文中,我们将仅使用默认构造函数的服务。

TweetClient Project - Object Browser TweetServiceClient Class Screen-Shot

TweetClient Project - Object Browser TweetServiceClient Methods Screen-Shot

既然我们有了服务引用,让我们定义我们的 TweetClientDataService

TweetClient Project - TweetClientDataService Class Screen-Shot

TweetClient Project - TweetClientDataService Class Implementation Screen-Shot

TweetClientDataService 实现(上图)中,我使用了对 TweetServiceClient 的引用。
TweetServiceClient 在后台为我们提供了大量功能!
例如TweetServiceClient - 在后台处理所有请求和响应 SOAP 信封的序列化和反序列化
它还为我们打开连接,并在网络上代表我们发送和接收信息。
因此,它确实抽象了在通过
RPC SAOP 风格的 Web Services 进行通信时
需要面对的许多复杂性!

测试我们上面创建的代理客户端

哇!我们在这里……我们几乎完成了!
我在 TweetClient 项目中创建了一个 Program 类,并引入了一些命令提示符
界面来与我们的 Tweet Web Service 操作进行交互。我将 TweetClient 中的 Program
项目留给您探索,因为它相当简单。

要运行 TweetClient 项目中的 Program 类,请按照下面的屏幕截图操作

TweetClient Project - Debug Program Class Screen-Shot

一个(您决定!)看起来不错的命令提示符界面将弹出,您可以使用它来调用我们的 Tweet Web Service 操作!

TweetClient Project - Awesome Command Prompt. Program Class in Action. Screen-Shot

玩得开心,使用 TweetClient 来操作我们的 TweetService!

最终想法

现在该我退场了。随时提出问题、提供反馈以及介于两者之间的任何内容,因为我和您在同一条船上。

附言:那艘船叫做“燃烧与学习”。

历史

  • 版本 1 提交于 2015 年 3 月 9 日
© . All rights reserved.