探索 Windows Communication Foundation - 第一部分






4.25/5 (36投票s)
从这篇文章开始,我们将探索 WCF 的各个方面
第二部分现已在 Code Project 发布,网址为 https://codeproject.org.cn/WCF/edujini_wcf_scart_02.asp。
也发布在 Eduzine© 的 这里。
引言
Microsoft .NET Framework 3.0 引入了 Windows Communication Foundation(简称 WCF)等组件。该框架使我们开发社区能够构建更多面向服务的应用程序。它包含了多项 Web 服务相关的规范,主要由 W3C 和 OASIS 联盟推动。我将只列出其中几项:
- SOAP 1.1, 1.2 及 Basic Profile 1.1
- WSDL 1.1
- MTOM
- WS Policy 和 WS Policy Attachments
- WS Metadata Exchange
- WSS SOAP Message Security 1.0, 1.1
- WSS SOAP Message Security Username Token Profile 1.0, 1.1
- WSS SOAP Message Security X.509 Token Profile 1.0, 1.1
- WS Addressing 2005/08
- WSS SOAP Message Security Kerberos Token Profile 1.1
- WS Secure Conversation
- WS Reliable Messaging
- WS Coordination
- WS Atomic Transaction
- WS Federation
从本文开始,让我们游览 WCF 的各个关键方面。
案例研究
我们将以简单的购物车作为案例研究。我们从简单的数据类型开始,然后逐步构建以处理自定义的、更复杂的数据类型。在本系列文章中,我们将探索 WCF 的各种关键方面。我希望在本系列中探讨的最低限度功能是:
- 发布 WCF 服务
- 编写 WCF 客户端
- 自定义操作契约详细信息,例如解耦 .NET 和契约名称,或将部分内容推送到 SOAP-
Envelope
的Headers
中 - 处理故障和错误
- 处理自定义数据类型
- 在操作中使用泛型数据
- 在操作中使用接口类型
- 在操作中使用集合
- 在操作中使用大数据
- 处理会话和事务
是的……这是一个很长的列表,但我会努力兑现我的承诺。不,所有文章目前都还没有准备好。我会在准备好时发布,并更新本文以提供链接。
好的……那么,让我们开始吧!
我们将需要以下项目来使用 WCF:
- Microsoft .NET Framework 2.0 可再发行组件 在此处
- Microsoft .NET Framework 2.0 SDK 在此处
- Microsoft .NET Framework 3.0 可再发行组件 在此处
- Microsoft Windows SDK for Windows Vista and .NET Framework 3.0 Runtime Components 在此处 您可以 在此处 下载完整镜像。
- 如果您使用 Visual Studio,请 在此处 下载扩展。
服务定义
我们的购物车服务,作为开始,发布以下操作:
bool CheckUserExists(string username);
DateTime? GetLastTransactionTime(string username);
第一个操作的目的是检查用户是否在我们数据库中注册。第二个操作返回最后一个用户执行的上次交易的日期和时间(如果存在)。是的,您没有看错,返回值类型不是 System.DateTime
,而是 System.DateTime?
,这是 System.Nullable<System.DateTime>
的 C# 语法。
要发布任何 WCF 服务,我们通常需要四个步骤:
服务契约定义
在 WCF 中,服务契约是指最终发布的某个服务。请注意,一个服务可能包含一个或多个相关的操作,在 WCF 中称为操作契约。
如果您在 Visual Studio 中进行开发,请创建一个类型为“类库”的新项目。是的,您没看错,是“类库”,而不是“WCF 服务库”。
我们首先创建一个名为 IShoppingCartService
的接口,如下所示:
using DateTime;
namespace ShoppingCartLibrary
{
public interface IShoppingCartService
{
bool CheckUserExists(string username);
DateTime? GetLastTransactionTime(string username);
}
}
契约实现
接下来显而易见的步骤是为服务提供实现。我们创建一个名为 ShoppingCartImpl
的类,它实现了 IShoppingCartService
接口。
using DateTime;
namespace ShoppingCartLibrary
{
public class ShoppingCartImpl : IShoppingCartService
{
public bool CheckUserExists(string username)
{
if(username == "gvaish" || username == "edujini")
{
return true;
}
return false;
}
public DateTime? GetLastTransactionTime(string username)
{
if(username == "gvaish")
{
return DateTime.Now.AddDays(-3);
}
if(username == "edujini")
{
return DateTime.Now.AddHours(-3);
}
return null;
}
}
}
服务配置
我们需要在两个级别进行配置:
- 使用特性,我们需要告知 WCF 关于 服务契约和操作契约 的信息。这些信息将用于定义服务、操作、消息和类型。
- 使用配置条目,我们需要告知 WCF 关于 要使用的实现类和绑定详情。这些详情将用于托管目的。
契约配置
如果您使用 Visual Studio,请从 GAC 添加对程序集 System.ServiceModel.dll 的引用。将 System.ServiceModel.ServiceContractAttribute
特性添加到接口。它告知 WCF 存在与相应类型关联的服务。将 System.ServiceModel.OperationContractAttribute
特性添加到接口中的方法。它会告知 WCF 要在服务中发布的这些操作。它将自行处理消息和关联的类型。
所以,我们的最终代码如下所示:
using DateTime;
using ServiceModel;
namespace ShoppingCartLibrary
{
[ServiceContract]
public interface IShoppingCartService
{
[OperationContract]
bool CheckUserExists(string username);
[OperationContract]
DateTime? GetLastTransactionTime(string username);
}
}
服务配置
我们将把这些详细信息提供给我们的 托管应用程序。
将文件编译成程序集。我将其命名为 ShoppingCartLibrary.dll
。如果您在命令行编译代码,请不要忘记添加对 System.ServiceModel.dll 的引用。
服务托管
在完全定义了我们的服务之后,我们需要一个运行时(引擎)来托管服务 - 一个允许客户端连接并调用操作的应用程序。为此,我们将创建一个控制台应用程序。该应用程序只有一个类 MainClass
,其中包含 Main
方法。
对于 Visual Studio 用户,我们将项目命名为 ShoppingCartHost
。将类 Program
重命名为 MainClass
。
添加对 System.ServiceModel.dll 和 ShoppingCartLibrary.dll 的引用。将以下代码写入 MainClass
。
using System;
using System.ServiceModel;
using ShoppingCartLibrary;
namespace ShoppingCartHost
{
public class MainClass
{
public static void Main(string[] args)
{
Uri uri = new Uri("https://:8080/ShoppingCartService");
using(ServiceHost host = new ServiceHost
(typeof(ShoppingCartImpl), uri))
{
host.Open();
Console.Write("Hit <Enter> to stop service...");
Console.ReadLine();
}
}
}
}
现在,我们需要如 前所述 的服务配置。将以下代码写入应用程序配置文件。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="HttpGetBehaviour">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="ShoppingCartLibrary.ShoppingCartImpl"
behaviorConfiguration="HttpGetBehaviour">
<endpoint binding="mexHttpBinding"
contract="ShoppingCartLibrary.IShoppingCartService"
address=""/>
</service>
</services>
</system.serviceModel>
</configuration>
编译您的代码。启动控制台应用程序。您应该会看到您的服务器已启动并正在运行。
浏览到 http://:8080/ShoppingCartService
的位置。
太棒了!我们的第一个服务准备好了。现在让我们设计一个客户端来使用该服务。
客户端应用程序
对于我们的客户端,我们需要两样东西:代理客户端代码和配置项。不不,您不需要编写任何一个。您可以使用 WCF 工具 svcutil.exe 生成它们。您可以在安装 Visual Studio IDE 的文件夹(默认位置为 %PROGRAMFILES%\Microsoft Visual Studio 8\Common7\IDE)或安装 .NET 3.0 SDK 的文件夹(默认位置为 %PROGRAMFILES%\Microsoft Windows SDK\v6.0\bin)中找到此工具。
确保 svcutil.exe 的位置已添加到您的路径中。在命令行中执行以下命令:
svcutil.exe /nologo /config:App.config
https://:8080/ShoppingCartService?wsdl
它将生成两个文件:ShoppingCartImpl.cs 和 App.config。我们只需要一个带有 Main
方法的 MainClass
来从客户端使用已发布的该服务。将以下代码写入该类:
using System;
namespace ShoppingCartConsumer
{
public class MainClass
{
public static void Main(string[] args)
{
ShoppingCartServiceClient client = new ShoppingCartServiceClient();
string[] users = new string[] { "gvaish", "edujini", "other" };
foreach(string user in users)
{
Console.WriteLine("User: {0}", user);
Console.WriteLine("\tExists: {0}",
client.CheckUserExists(user));
DateTime? time = client.GetLastTransactionTime(user);
if(time.HasValue)
{
Console.WriteLine("\tLast Transaction: {0}", time.Value);
} else
{
Console.WriteLine("\tNever transacted");
}
}
Console.WriteLine();
}
}
}
不要忘记添加对 System.ServiceModel.dll 的引用。构建您的项目。执行客户端。您应该会看到类似下面显示的输出:
请注意,这只是一个开始……所以,如果您正在寻找高级主题,请多一点耐心。
注释
我们选择将接口作为我们的服务契约。通常,我们可以直接使用一个类作为服务契约。然而,最好始终采用接口,然后提供实现。这样,我们可以独立且模块化地维护契约的声明和契约的实现。
摘要
借助 WCF,可以非常简单地发布和使用 Web 服务。发布 Web 服务不像在 ASP.NET 中那样简单。但是,正如表面上可能注意到的那样,WCF 可能比 ASP.NET 服务更加灵活。我们看到的灵活性之一是可以在 ASP.NET 运行时之外对其进行托管。
联系方式
- 您可以直接在下方评论,我将回复。
- 您可以通过 gaurav.vaish@gmail.com 直接联系我。
- 如果您正在寻找关于 Microsoft .NET Framework 2.0/3.0、Java 1.5/1.6、Web 服务或面向服务的体系结构 (SOA) 的任何专业工作,请联系我的雇主 Edujini™ Labs,网址为 http://www.edujini-labs.com。
版本历史
- 初始提交
- 更新了简介,使其比之前的更好。
- 提供了本系列第二篇文章的详细信息 - 该文章现已在 Code Project 上发布。