zoukankan      html  css  js  c++  java
  • [玩转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.

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

  • 相关阅读:
    用魔数防范文件上传攻击
    nginx http跳转到https
    tengine安装
    版本标记说明
    nginx基于域名的虚拟主机 反向代理配置实例
    非ROOT用户启动Tomcat
    使用druid连接池的超时回收机制排查连接泄露问题
    Jenkins入门系列之
    centos7 关闭SELINUX 防火墙
    mac安装IE浏览器
  • 原文地址:https://www.cnblogs.com/anytao/p/anytao_silverlight_03_rest_part1.html
Copyright © 2011-2022 走看看