[玩转Silverlight]第三回:基础篇,在Silverlight中使用基于WCF的REST服务(上)

《你必须知道的.NET》网站 | Anytao技术博客 

[玩转Silverlight]第三回:基础篇,在Silverlight中使用基于WCF的REST服务(上)

发布日期:2009.02.19 作者:Anytao
© 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处。

REST(Representational State Transfer,具象状态传输)是个好东西,具有诸多的优点值得拿来分享,在WEB更加开放的今天,尽管我们不能否认SOAP在客户端-服务器交互中的大放异彩,但同样也不能抹杀其他技术带来的独特风景和魅力,REST就是其中之一。同时,作为.NET 3.5中WCF框架的重量级飞跃,基于WCF的RESTful服务也让习惯了.NET平台的追随者看到曙光,那么本文的目的正是在上述技术的基础上通过Silverlight视角来消费崭新的REST服务,带领大家体验一下RESTful在Silverlight中的应用。

什么是REST?

最早的REST概念,由Roy Fielding在Architectural Styles and the Design of Network-based Software Architectures一文提出,利用现有的技术(REST是基于HTTP协议的)实现通过唯一URI来操作唯一资源的方式提供WEB服务。例如,可以通过

http://www.anytao.com/book/insidenet/ch1

方式来读取[你必须知道的.NET]一书第一章的内容,而通过

http://www.anytao.com/book/insidenet/ch1/create

或者

http://www.anytao.com/book/insidenet/ch1/delate

来增加或者删除相应的内容。

你看,RESTful服务更加符合人类的习惯思维,简化了资源与操作在web架构中的体系结构,总结起来REST应用的基本原则体现在以下几个方面:

  • 通过URI标识唯一的资源,并通过HTTP谓词(GET, POST, PUT, DELETE)进行资源操作。
  • 资源是自描述的,意味着资源的信息包含在资源请求本身,我们将在后面的示例中感受。
  • 所有的操作都是无状态的。

如果对REST还有更多了解兴趣,可以参考:Building Web Services the REST Way的详细介绍。那么,REST有什么样的优点值得吸引我们的目光呢?除了其处理资源的方式更加符合我们的习惯思维,其强大的优势还体现在:

  • 简单易懂。URI本身就公开了所有操作的意义,那么对于WEB消费而言,其简单性来得直截了当,因此我喜欢。
  • 统一接口设计。统一接口设计是基于统一资源操作的必然结果,实现了服务层次的低耦合,保证了系统的简化。
  • 扩展性。因为资源是自描述的,那么其本身包含了所有的必要信息,对于扩展而言这是最方便的机制。

下面是关于REST一些有用的资源,仅供参考:

既然有这么多眼花缭乱的好处和愿景,那么我们就可以开始利用WCF小试牛刀喽:-)

创建基于WCF的RESTful服务

必要的准备

为了实现一个常用的REST服务场景,就必须首先搭建一个必要的舞台:

其中包括以下几个实体:

  • User,用户
  • Post,用户发布的文章
  • Comments,文章的评论

同时对外提供以下的服务:

  • GetAllUsers(),获取所有的用户信息
  • GetPostsByName(),按照用户名称获取其发布的所有文章信息
  • GetPostByID(),按照文章ID获取该篇文章信息
  • GetCommentByAuthor(),按照评论者姓名获取其评论信息
  • AddComment(),添加按照文章添加评论

详细的情况,我们将在后文的创建过程中逐层解开。

WCF的REST基础

.NET 3.5中实现了WCF的扩展从而可以在SOAP和REST中作出更多的选择,我们在了解REST的基础上就可以轻而易举的对WCF的REST支持有个快速的认知。首先,值得关注的是WCF中一系列重要的支持框架,需要重点关注的是:

  • WebGetAttribute和WebInvokeAttribute,其中WebGet标识调度程序响应HTTP GET请求,而WebInvoke则标示调度程序响应任何HTTP请求,其中以WebInokeAttribute.Method属性来标识,默认情况下映射为HTTP POST。以WebGet为例,
[AttributeUsage(AttributeTargets.Method)]
public sealed class WebGetAttribute : Attribute, IOperationBehavior, IWmiInstanceProvider
{
    public WebGetAttribute();
    public WebMessageBodyStyle BodyStyle { get; set; }
    public bool IsBodyStyleSetExplicitly { get; }
    public bool IsRequestFormatSetExplicitly { get; }
    public bool IsResponseFormatSetExplicitly { get; }
    public WebMessageFormat RequestFormat { get; set; }
    public WebMessageFormat ResponseFormat { get; set; }
    public string UriTemplate { get; set; }
}

其中UriTemplate是WCF为每种资源以模板的方式定义URI,使用方法和动词的组合,例如:

[WebInvoke(UriTemplate = "/{name}/{post}", Method = "POST")]
Comment AddComment(string name, string post, Comment comment);

RequestFormat和ResponseFormat是WebMessageFormat类型的成员,其表示了Request和Response过程的传输格式为Xml或者Json:

public enum WebMessageFormat
{
    Xml = 0,
    Json = 1,
}

那么,按照WCF REST定义语法,我们开始定义一个完整的IPostService Contract如下:

// Release : 2009/02/12                            
// Author  : Anytao, http://www.anytao.com 
[ServiceContract(Namespace="http://api.anytao.com/rest/")]
public interface IPostService
{
    [OperationContract]
    [WebGet(UriTemplate = "/", ResponseFormat = WebMessageFormat.Xml)]
    List<User> GetAllUsers();

    [OperationContract]
    [WebGet(UriTemplate = "/{name}", ResponseFormat = WebMessageFormat.Xml)]
    List<Post> GetPostsByName(string name);

    [OperationContract]
    [WebGet(UriTemplate = "/{name}/{post}", ResponseFormat = WebMessageFormat.Json)]
    Post GetPostByID(string name, string post);

    [OperationContract]
    [WebGet(UriTemplate = "/{name}/{post}/{comment}", ResponseFormat = WebMessageFormat.Json)]
    Comment GetCommentByAuthor(string name, string post, string comment);

    [OperationContract]
    [WebInvoke(UriTemplate = "/{name}/{post}", Method = "POST")]
    Comment AddComment(string name, string post, Comment comment);
}
  • WebHttpBinding和WebHttpBehavior,就像BasicHttpBinding和BasicHttpBehavior一样,用于确定WCF的通信方式,WebHttpBinding用于为通过HTTP请求公开的WCF服务配置终结点,WebHttpBehavior则完成对于“URI+谓词”的启动,为WebHttpBinding支持Web样式服务提供支持。像一般的WCF服务一样,WebHttpBinding可以通过编码方式和配置方式两种途径完成,当然我们更推荐的是配置方式:
  <bindings>
    <webHttpBinding>
      <binding name="secure">
        <security mode="Transport">
          <transport clientCredentialType="Basic"/>
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="postbehavior">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  • WebServiceHost和WebServiceHostingFactory,顾名思义WebServiceHost承载利用配置终结点的绑定,而WebServiceHostingFactory利用工厂模式进行WebServiceHost的创建工作。在Self Host时,我们可以利用WebServiceHost简化对WebHttpBinding和WebHttpBehavior的配置过程,例如:
// Release : 2009/02/19                            
// Author  : Anytao, http://www.anytao.com 

static void Main(string[] args)
{
    string baseUri = "http://localhost:6666/PostService";
    WebServiceHost sh = new WebServiceHost(typeof(PostService),
                                        new Uri(baseUri));

    sh.Opened += (s1,s2) =>
        {
            Console.WriteLine("Service begin to listen via {0}", baseUri);
        };

    sh.Open();
    Console.ReadLine();
}

我们将在下面的创建过程中逐步接触这些概念及其应用。

Note:下面是WCF REST的有用资源:WCF REST Starter Kit 

实现WCF的REST服务

实现WCF的REST服务和一般的WCF服务并无二致,都是通过实现契约接口,对提供的服务进行具体实现,限于篇幅我们仅将GetPostByName服务做以举例:

// Release : 2009/02/19                            
// Author  : Anytao, http://www.anytao.com 

public class PostService : IPostService
{
    private List<User> users;

    public List<Post> GetPostsByName(string name)
    {
        User user = (from u in users
                     where u.Name == name
                     select u).Single();

        return user.Posts;
    } 
}

下篇预告

在下篇,我们将在本文理论分析的基础上,实现一个具体的消费实例,主要包括以下内容:

  • 两种方式Host WCF RESTful服务
  • 在Silverlight中消费WCF RESTful服务

敬请关注。

参考文献

温故知新

anytao | © 2009 Anytao.com

2009/02/19 | http://anytao.cnblogs.com/

本文地址:http://www.cnblogs.com/anytao/archive/2009/02/19/anytao_silverlight_03_rest_part1.html

本文以“现状”提供且没有任何担保,同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

posted @ 2009-02-19 00:21  Anytao  阅读(4472)  评论(4编辑  收藏  举报