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

探索 Windows Communication Foundation - 第一部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (36投票s)

2007年1月21日

BSD

7分钟阅读

viewsIcon

130622

downloadIcon

780

从这篇文章开始,我们将探索 WCF 的各个方面

第二部分现已在 Code Project 发布,网址为 https://codeproject.org.cn/WCF/edujini_wcf_scart_02.asp
也发布在 Eduzine© 的 这里

Exploring WCF (Part 1)

引言

Microsoft .NET Framework 3.0 引入了 Windows Communication Foundation(简称 WCF)等组件。该框架使我们开发社区能够构建更多面向服务的应用程序。它包含了多项 Web 服务相关的规范,主要由 W3C 和 OASIS 联盟推动。我将只列出其中几项:

  1. SOAP 1.1, 1.2 及 Basic Profile 1.1
  2. WSDL 1.1
  3. MTOM
  4. WS Policy 和 WS Policy Attachments
  5. WS Metadata Exchange
  6. WSS SOAP Message Security 1.0, 1.1
  7. WSS SOAP Message Security Username Token Profile 1.0, 1.1
  8. WSS SOAP Message Security X.509 Token Profile 1.0, 1.1
  9. WS Addressing 2005/08
  10. WSS SOAP Message Security Kerberos Token Profile 1.1
  11. WS Secure Conversation
  12. WS Reliable Messaging
  13. WS Coordination
  14. WS Atomic Transaction
  15. WS Federation

从本文开始,让我们游览 WCF 的各个关键方面。

案例研究

我们将以简单的购物车作为案例研究。我们从简单的数据类型开始,然后逐步构建以处理自定义的、更复杂的数据类型。在本系列文章中,我们将探索 WCF 的各种关键方面。我希望在本系列中探讨的最低限度功能是:

  • 发布 WCF 服务
  • 编写 WCF 客户端
  • 自定义操作契约详细信息,例如解耦 .NET 和契约名称,或将部分内容推送到 SOAP-EnvelopeHeaders
  • 处理故障和错误
  • 处理自定义数据类型
  • 在操作中使用泛型数据
  • 在操作中使用接口类型
  • 在操作中使用集合
  • 在操作中使用大数据
  • 处理会话和事务

是的……这是一个很长的列表,但我会努力兑现我的承诺。不,所有文章目前都还没有准备好。我会在准备好时发布,并更新本文以提供链接。

好的……那么,让我们开始吧!

我们将需要以下项目来使用 WCF:

  1. Microsoft .NET Framework 2.0 可再发行组件 在此处
  2. Microsoft .NET Framework 2.0 SDK 在此处
  3. Microsoft .NET Framework 3.0 可再发行组件 在此处
  4. Microsoft Windows SDK for Windows Vista and .NET Framework 3.0 Runtime Components 在此处 您可以 在此处 下载完整镜像。
  5. 如果您使用 Visual Studio,请 在此处 下载扩展。

服务定义

我们的购物车服务,作为开始,发布以下操作:

bool      CheckUserExists(string username);
DateTime? GetLastTransactionTime(string username);

第一个操作的目的是检查用户是否在我们数据库中注册。第二个操作返回最后一个用户执行的上次交易的日期和时间(如果存在)。是的,您没有看错,返回值类型不是 System.DateTime,而是 System.DateTime?,这是 System.Nullable<System.DateTime> 的 C# 语法。

要发布任何 WCF 服务,我们通常需要四个步骤:

  1. 服务契约定义
  2. 契约实现
  3. 服务配置
  4. 服务托管

服务契约定义

在 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;
        }
    }
}

服务配置

我们需要在两个级别进行配置:

  1. 使用特性,我们需要告知 WCF 关于 服务契约和操作契约 的信息。这些信息将用于定义服务、操作、消息和类型。
  2. 使用配置条目,我们需要告知 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.dllShoppingCartLibrary.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>

编译您的代码。启动控制台应用程序。您应该会看到您的服务器已启动并正在运行。

host application

浏览到 http://:8080/ShoppingCartService 的位置。

browse location

太棒了!我们的第一个服务准备好了。现在让我们设计一个客户端来使用该服务。

客户端应用程序

对于我们的客户端,我们需要两样东西:代理客户端代码和配置项。不不,您不需要编写任何一个。您可以使用 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.csApp.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 的引用。构建您的项目。执行客户端。您应该会看到类似下面显示的输出:

client application

请注意,这只是一个开始……所以,如果您正在寻找高级主题,请多一点耐心。

注释

我们选择将接口作为我们的服务契约。通常,我们可以直接使用一个类作为服务契约。然而,最好始终采用接口,然后提供实现。这样,我们可以独立且模块化地维护契约的声明和契约的实现。

摘要

借助 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 上发布。
© . All rights reserved.