技术开发 频道

使用WCF和.NET 3.5 进行HTTP编程

  REST 和 Web

  通过查看 HTTP 传输的一些关键部分,您也已经看到了将 Web 松散地联结在一起的一些重要原则。2000 年,一位名叫 Roy Fielding 的博士生完成了一篇论文,其中一项工作就是将这些原则汇编形成了一种体系结构风格,也就是所谓的具像状态传输 (Representational State Transfer, REST)。(您可以在 ics.uci.edu/~fielding/pubs/dissertation/top.htm 找到 Roy 的论文。)
各种书籍、软件会议以及看起来无数的博客已经对 REST 体系结构风格进行了详细的讨论。此处不可能对它面面俱到,但我认为应该可以把它浓缩为三个要点:
  • 利用 URI
  • HTTP GET 具有特殊性
  • Content-Type 是数据模型
  为了撰写本文的目的,我们假设这些要点就是 Web 的原则。通过将这些原则结合到应用程序中,即可大大增强互操作性以及应用程序功能的作用范围。互操作性和作用范围是大多数 Web 服务举措背后的关键驱动因素。毕竟,Web 服务实质上就是一个通过结构化消息传递架构来提供某种功能的方法。Web(HTTP 请求/响应)的原则实际描述了可能的消息传递架构的子集。事实上,所有平台、应用程序、操作系统和用户都了解 Web 原则,因此将其结合在您的 Web 服务应用程序中即可提高它的作用范围和互操作性。

  需要注意的是,由于 REST 和 WS-* 之间的选择并不相互排斥,因此 Web 原则对 WS-* 没有影响。它们中任何一个都不能解决所有类型的通信要求,因此建议您不要在自己构建的所有服务上一股脑地应用其中一个。例如,REST 不擅长于向中介发送消息,而 WS-* 却擅长于此。另一方面,WS-* 应用程序不太擅长与诸如浏览器等简单的客户端交互,但 REST 在这方面却十分出色。
 
  使用 WCF 进行 HTTP 编程

  基于这些 Web 基础知识,我们再看看在 .NET Framework 3.5 中使用 WCF 来构建符合 Web 原则的应用程序。首先,我将介绍 HTTP 编程模型中一些新的构建块,然后向上介绍整个系统。

  如果要“利用 URI”,您可能需要习惯构建和分析 URI。手动执行这项任务往往容易出错且十分枯燥。然而,新的 System.UriTemplate 和 System.UriTemplateMatch 类型挑起了构建和分析 URI 这个重担,而它们也是 WCF 新的 HTTP 功能中的基础构建块。

  UriTemplate 类型是定义上文中所述 URI 孔的基础构建块。UriTemplate 类型的构造函数可以接受代表 URI 中孔的 String。在实例化时,UriTemplate 对象会提供两个实例方法,将文本值与在实例化中定义的孔绑定。这些方法会返回一个 URI,它的孔已填充了值。

  UriTemplate 对象同样也会提供一个名为 Match 的实例方法,用于从 System.Uri 对象的孔提取值。Match 实例方法可以接受两个 System.Uri 对象。第一个 Uri 是基本地址,第二个 Uri 是用于匹配的候选项目。System.UriTemplateMatch 对象是 Match 方法返回的值。UriTemplateMatch 对象包含一组值,用于 UriTemplate 实例化时定义的孔。

  图 2
中的代码阐明了如何使用 UriTemplate 和 UriTemplateMatch 类型来回处理了一次 Uri。此代码的结果输出如下所示:

Figure 2 Creating a Template-Based URI

// create a URI bound to the template
Uri baseAddress = new Uri(@"http://localhost:2000");
UriTemplate template
= new UriTemplate("{artist}?album={album}");
Uri boundUri
= template.BindByPosition(baseAddress, "Northwind",
    
"Overdone");
Console.WriteLine(boundUri.ToString());
            
// retrieve the value of the artist segment
UriTemplateMatch match = template.Match(baseAddress, boundUri);
String bandName
= match.BoundVariables["artist"];
Console.WriteLine(
"the name of the artist is  {0}", bandName);

 

http://localhost:2000/Northwind?album=Overdone
the name of the artist is  Northwind

  System.UriTemplate 和 System.UriTemplateMatch 类型在命名空间中忽略了常见的 WCF System.ServiceModel 标记。这是因为它们的功能使您无需在 WCF 应用程序内部使用这两种类型。任何时候您需要创建或分析 URI,它们使用起来都非常方便。

  虽然 UriTemplate 和 UriTemplateMatch 类型使用起来已经非常容易了,但 WCF 小组还想进一步简化这两种类型在 WCF 服务中的使用。目标是提供一种简单而直观的方法,将 URI 段和查询字符串参数映射到应用程序功能中。我想下面代码中所展示的模型就符合这个目标:
 
[ServiceContract]
public interface IPictureService
{
  [OperationContract]
  [WebGet(UriTemplate
= "picture/{pictureId}")]
  Stream GetPicture(String pictureId);

  [OperationContract]
  [WebGet(UriTemplate
= "picture/t/{pictureId}")]
  Stream GetPictureThumbnail(String pictureId);
}

  UriTemplate 表面上看起来是 WebGetAttribute 上的一个实例属性,而 WebGetAttribute 又随之应用到某个服务约定。请注意,大括号间的标记映射到方法参数的名称。虽然这个示例只显示了一个参数,但您可以添加多个参数,以任何顺序排列,将其作为查询字符串参数,甚至可以使用通配符。

  运行时,UriTemplate 属性的值会被传递到 UriTemplate 构造函数。无论是 Client 运行时,还是 Dispatcher,都以这种方式使用 UriTemplate 属性值。Dispatcher 用它将传入消息与某个操作匹配,而 Client 则用它确保代理应用程序上的方法被发送到正确的 URI。这种方法不仅简单易用,而且可以有效地在您的服务中“利用 URI”。
0
相关文章