使用RestSharp 库消费Restful Service

现在互联网上的服务接口都是Restful的,SOAP的Service已经不是主流。.NET/Mono下如何消费Restful Service呢,再也没有了方便的Visual Studio的方便生产代理的工具了,你还在用HttpWebRequest 自己封装吗?Restful Service还有授权问题,自己写出来的代码是不是很不优雅?通常Restful Service返回的数据格式是XML或者Json,还要设置服务的输入参数等等,使用起来很复杂。本文向你推荐一个开源的库RestSharp轻松消费Restful Service。RestSharp是一个开源的.NET平台下REST和Http API的客户端库,支持的平台有.NET 3.5/4、Mono、Mono for Android、MonoTouch、Windows Phone 7.1 Mango。他可以简化我们访问Restful服务,可以到这里下载代码 https://github.com/johnsheehan/RestSharp/archives/master 更简单的使用NuGet。RestSharp使用Json.Net处理 Json数据同Poco对象的序列化。

下面分别从库的使用方式上进行介绍,使用的Restful Service是腾讯社区开放平台(http://opensns.qq.com/)。 
1、服务认证,RestSharp定义了一个认证授权的接口 IAuthenticator ,有NtlmAuthenticator、HttpBasicAuthenticator、OAuth1Authenticator、OAuth2Authenticator几种,基本上可以满足要求了,腾讯社区开放平台使用OAuth2,腾讯社区开放平台额外增加了一个OpenId的参数,我们从OAuth2Authenticator的基类继承实现一个:

    public class OAuthUriQueryParameterAuthenticator : OAuth2Authenticator 
    { 
        private readonly string openId; 
        private readonly string consumerKey;

        public OAuthUriQueryParameterAuthenticator(string openId, string accessToken, string consumerkey) 
            :base(accessToken) 
        { 
            this.openId = openId; 
            this.consumerKey = consumerkey; 
        }

        public override void Authenticate(IRestClient client, IRestRequest request) 
        { 
            request.AddParameter("access_token", AccessToken, ParameterType.GetOrPost); 
            request.AddParameter("openid", openId, ParameterType.GetOrPost); 
            request.AddParameter("oauth_consumer_key", consumerKey, ParameterType.GetOrPost); 
        }

2、Get请求方法,下面的例子是根据access_token获得对应用户身份的openid: https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN

     public string GetOpenId(string accessToken) 
      {

          RestClient  _restClient = new RestClient(Endpoints.ApiBaseUrl); 
          var request = _requestHelper.CreateOpenIDRequest(accessToken); 
          var response = Execute(request); 
          var openid = GetUserOpenId(response.Content); 
          return openid; 
      }

       private RestSharp.RestResponse Execute(RestRequest request) 
       {

       //返回的结果

           var response = _restClient.Execute(request);

           if (response.StatusCode != HttpStatusCode.OK) 
           { 
               throw new QzoneException(response); 
           } 
           return response; 
       }

       internal RestRequest CreateOpenIDRequest(string accesstoken) 
       { 
           var request = new RestRequest(Method.GET); 
           request.Resource = "oauth2.0/me?access_token={accesstoken}"; 
           request.AddParameter("accesstoken", accesstoken, ParameterType.UrlSegment); 
           return request; 
       }

      上面代码里涉及到了服务的输入参数通过AddParameter方法很方便的处理,是不是很简单。

3、POST请求服务,下面的例子是发表一条微博信息(纯文本)到腾讯微博平台上http://wiki.opensns.qq.com/wiki/%E3%80%90QQ%E7%99%BB%E5%BD%95%E3%80%91add_t

        /// <summary> 
        /// 发表一条微博信息(纯文本)到腾讯微博平台上 
        /// </summary> 
        /// <param name="content">表示要发表的微博内容。必须为UTF-8编码,最长为140个汉字,也就是420字节。 
        /// 如果微博内容中有URL,后台会自动将该URL转换为短URL,每个URL折算成11个字节。</param> 
        /// <param name="clientip">用户ip,以分析用户所在地</param> 
        /// <param name="jing">用户所在地理位置的经度。为实数,最多支持10位有效数字。有效范围:-180.0到+180.0,+表示东经,默认为0.0</param> 
        /// <param name="wei">用户所在地理位置的纬度。为实数,最多支持10位有效数字。有效范围:-90.0到+90.0,+表示北纬,默认为0.0。</param> 
        /// <param name="syncflag">标识是否将发布的微博同步到QQ空间(0:同步; 1:不同步;),默认为0.</param> 
        /// <returns></returns> 
        internal AddWeiboResult AddWeibo(string content, string clientip = "", string jing = "", string wei = "", int syncflag = 0) 
        {

        RestClient  _restClient = new RestClient(Endpoints.ApiBaseUrl);

             _restClient.Authenticator = new OAuthUriQueryParameterAuthenticator(context.AccessToken.OpenId, context.AccessToken.AccessToken, context.Config.GetAppKey()); 
            var request = _requestHelper.CreateAddWeiboRequest(content, clientip,jing,wei,syncflag);

            var response = Execute(request);            
            var payload = Deserialize<AddWeiboResult>(response.Content); 
            return payload; 
        }

       internal RestRequest CreateAddWeiboRequest(string content, string clientip, string jing, string wei, int syncflag) 
        { 
            var request = new RestRequest(Method.POST); 
            request.RequestFormat = DataFormat.Json; 
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded"); 
            request.Resource = "t/add_t"; 
            request.AddParameter("content", content); 
            if (!string.IsNullOrEmpty(clientip)) 
            { 
                request.AddParameter("clientip", clientip); 
            } 
            if (!string.IsNullOrEmpty(jing)) 
            { 
                request.AddParameter("jing", jing); 
            } 
            if (!string.IsNullOrEmpty(wei)) 
            { 
                request.AddParameter("wei", wei); 
            } 
            request.AddParameter("syncflag", syncflag); 
            return request; 
        }

   这个方法需要使用到OAuth2的认证和前面的不需要认证的接口比较起来并没有变复杂,代码很优雅。

4、来点复杂的,发个图片微博,RestSharp对HttpFile的封装也很不错,使用起来一样很简单,看代码中的红色部分:

internal RestRequest CreateAddPictureWeiboRequest(string content, string clientip, string jing, string wei, int syncflag, string fileName, byte[] bytes) 
       { 
           var request = new RestRequest(Method.POST); 
           request.RequestFormat = DataFormat.Json; 
           var boundary = string.Concat("--", Util.GenerateRndNonce()); 
           request.AddHeader("Content-Type", string.Concat("multipart/form-data; boundary=", boundary)); 
           request.Resource = "t/add_pic_t"; 
           request.AddParameter("content", content); 
           if (!string.IsNullOrEmpty(clientip)) 
           { 
               request.AddParameter("clientip", clientip); 
           } 
           if (!string.IsNullOrEmpty(jing)) 
           { 
               request.AddParameter("jing", jing); 
           } 
           if (!string.IsNullOrEmpty(wei)) 
           { 
               request.AddParameter("wei", wei); 
           } 
           request.AddParameter("syncflag", syncflag); 
           request.AddFile("pic", bytes, fileName); 
           return request; 
       }

上面这几个API的调用已经很具有代表性了,是不是可以很好的简化你使用Restful Service,记住DRY(don’t repeat yourself),可以很好的加速你的应用的开发。

Quartz.NET的管理工具

很多同学都在用Quartz.NET做任务调度,任务调度情况怎么样啊,需要暂停某个任务,运行下某个任务,需要有管理工具的支持,本篇文章是向你介绍Quartz.NET的管理工具方面的几个开源项目。工具有两类:完整的一个管理站点和嵌入你的项目里头的一个模块。

1、quartznet-admin 是一个完整的asp.net mvc的Quartz.NET 管理应用,地址是 http://code.google.com/p/quartznet-admin/ ,这个项目目前也没有发布出来的版本,自己可以去下载代码下来编译,但是这个项目有好几个月都没有活动了,估计会有些问题,开源的项目自己搞定没问题。

2、QuartzNetWebConsole 是一个可以插入你网站里头的一个模块 ,地址是https://github.com/mausch/QuartzNetWebConsole 。这个项目适合于在你的ASP.NET网站里面使用。如果你的任务是使用Windows服务方式承载的,那就得使用quartznet-admin或者是crystal-quartz

3、crystal-quartz 也是一个模块,地址是http://code.google.com/p/crystal-quartz/,可以很方便的集成到的管理网站里头,它提供了2个提供者CrystalQuartz.Simple(和QuartzNetWebConsole一样在Web里头直接承载调度任务)和CrystalQuartz.Remote(用于使用Windows服务方式承载任务调度,远程管理方式)。

4、QuartzNetManager 是一个完整Quartz.NET的WPF写的管理工具,地址是https://github.com/adometry/QuartzNetManager

Protocol Buffers 是在一个很理想的结构化数据的语言中立的序列化格式。你可以考虑一下XML或JSON,但更轻,更小的协议缓冲区。 这种格式的广应用于谷歌不同的系统之间交换数据。

由于其结构化数据的最佳表现,protocol buffers 是一个代表RESTful服务处理的数据很好的选择。要遵循REST的原则, protocol buffers 应作为一个新的超媒体类型的代表。 在当前版本(.NET 4) 的Windows通讯基础(WCF),包含一个新的媒体类型,需要相当数量的努力。 幸运的是,新版本的WCF HTTP堆栈,使媒体类型的WCF编程模型的一等公民,大家可以Glenn Block’s 博客去了解更详细的内容。推荐大家假期可以看下这本书《REST实战》http://book.douban.com/subject/6854551/

下面我们来介绍如何使用Google Protocol Buffers,只定义一个超媒体类型 ProtoBufferFormatter:

自定义超媒体类型是通过创建自定义的MediaTypeFormatter,实现OnWritetoStream() 和 OnReadFromStream() 方法进行序列化和反序列化处理。人们经常认为媒体类型只是在服务端使用,但是它用来在客户端控制序列化和反序列化的要求,下图显示了一个HTTP 请求/响应和媒体类型格式化扮演的角色:

MediaTypeFormatterProcess

这个例子我们使用入门:构建简单的Web API 的代码和WCF Web API Preview 6。使用的媒体类型是application/x-protobuf ,REST服务的核心原则就是服务器和客户端之间的松耦合性,客户端需要知道书签的URI,但不应该知道任何其他的URI的知识,但是客户端必须知道链接关系。

image

下面的代码是自定义的ProtoBufferFormatter,构造函数里指明了支持的媒体类型 application/x-protobuf。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Net.Http.Formatting; 
using System.IO; 
using ProtoBuf; 
using ProtoBuf.Meta;

namespace WcfWebFormat.Formatters 

    public class ProtoBufferFormatter : MediaTypeFormatter 
    { 
        public ProtoBufferFormatter() 
        { 
            this.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-protobuf")); 
        }

        protected override void OnWriteToStream(Type type, object value, Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, System.Net.TransportContext context) 
        { 
            Serializer.Serialize(stream, value);  
        }

        protected override object OnReadFromStream(Type type, Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders) 
        { 
            object obj = (RuntimeTypeModel.Default).Deserialize(stream, null, type); 
            return obj; 
        }

    } 
}

如上所示,我们在OnWriteToStream方法中将.NET对象序列化为ProtoBuf格式,在OnReadFromStream方法中将ProtoBuf格式饭序列化为.NET对象。

现在需要给我们的.NET对象加入ProtoBuf 序列化的标签:

using System.Collections.Generic; 
using System.Xml.Serialization; 
using ProtoBuf;

namespace ContactManager.Resources 

    [ProtoContract] 
    public class Contact 
    { 
        [ProtoMember(1)] 
        public int ContactId { get; set; } 
        [ProtoMember(2)] 
        public string Name { get; set; } 
    } 
}

把ProtoBufferFormatter 加入到WCF运行时的超媒体类型集合里。

using Microsoft.ApplicationServer.Http; 
using WcfWebFormat.Formatters;

namespace ContactManager 

    public class ContactManagerConfiguration : HttpConfiguration 
    { 
        public ContactManagerConfiguration() 
        { 
            this.Formatters.Add(new ProtoBufferFormatter()); 
        } 
    } 
}

修改服务配置,使用ContactManagerConfiguration:

var config = new ContactManagerConfiguration() { EnableTestClient = true }; 
routes.Add(new ServiceRoute("api/contacts", new HttpServiceHostFactory() { Configuration = config }, typeof(ContactsApi)));

在客户端调用的代码如下:

           var serviceUri = new Uri("http://localhost:9000/api/contacts/"); 
            var httpClient = new HttpClient(); 
            httpClient.BaseAddress = serviceUri; 
            httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/x-protobuf"));

            var response = httpClient.GetAsync("1").Result; 
            Contact obj = (RuntimeTypeModel.Default).Deserialize(response.Content.ReadAsStreamAsync().Result, null, typeof(Contact)) as Contact;

            var formatters = new MediaTypeFormatterCollection() { new ProtoBufferFormatter() };
            var content = new ObjectContent<Contact>(obj, "application/x-protobuf",formatters);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/x-protobuf");

            httpClient.PostAsync(serviceUri,content);

即使目前来说Google Protocol Buffers没有XML/JSON那样普及,RESTful服务使用中ProtoBuf无疑是一个非常有效的超媒体类型。祝大家龙年新春愉快,吉祥如意!

相关文章:

  • 软件系统开发中的数据交换协议
  • .net自带二进制序列化,XML序列化和ProtoBuf序列化的压缩对比
  • Android上GTalk以及Push机制的XMPP数据选择使用protobuf格式而非XML
  • Leverage T4Scaffolding for WCF Web API
  • using-protocol-buffers-on-net-platform-part-i
  • using-protocol-buffers-on-net-platform-part-ii
  • Restful WCF / EF POCO / UnitOfWork / Repository / MEF : 1 of 2
  • 两种常见的分布式应用架构风格包括:DO(分布式对象)、RPC(远程过程调用)。这两种架构风格在企业应用中得到了广泛的应 
    用,然而,Web架构的设计者们却有意避免采用这两种架构风格。主要的原因是运行Web应用的互联网环境,与运行企业应用的企业内网环境有很大的差别。 
    那么,互联网环境有哪些独有的特点呢? 
    1. 可伸缩性要求难以预测和无法控制:一个Web应用的并发访问量,是开发者难以预测和无法控制的。 
    2. 安全性要求难以预测和无法控制:一个Web应用所接受的请求格式,是开发者难以预测和无法控制的,有可能出现大量恶意构造的请求格式。 
    3. 松耦合至关重要:因为存在着大量异构的系统,必须要追求最大限度的松耦合。 
    4. 简单性至关重要:不可引入复杂的编程模型,必须降低开发者开发Web应用的门槛。

    软件应用所处的运行环境会对其架构设计产生巨大影响。设计软件应用的架构,一定要深入考虑软件所处的运行环境。脱离开软件所处的运行环境,比较不同架构 
    之间的优劣是没有意义的。

    REST这种架构风格,正是为面向互联网的Web应用量身定制的。它由一组架构约束组成: 
    1. 客户-服务器 
    2. 无状态 
    3. 缓存 
    4. 统一接口 
    5. 分层系统 
    6. 按需代码(可选)

    上述内容来自《REST实战》译者序。.NET上的分布式应用架构风格从WCF开始统一了Remoting,SOAP,以及对REST的支持。现在我们来看下最新的.NET平台上都有哪些REST框架和工具库:

    1. WCF WebHttp Services in .NET 4 :WCF 3.5开始支持REST,实现方式上还是RPC 方式,Windows Communication Foundation (WCF)Web HTTP 编程模型可以向非 SOAP 终结点公开 WCF 服务操作。文档地址 http://msdn.microsoft.com/zh-cn/library/bb412169.aspx 

    2. WCF WebApi:这是完全按照HTTP模型实现的REST,目前还处于预览版,WCF Web API允许开发人员通过HTTP开放他们的应用程序、数据和服务。这允许开发人员可以充分利用HTTP作为应用程序的协议,应用程序可以和丰富的客户端进行交互,不仅仅是浏览器、移动设备、桌面应用还是其他的后端服务。文档地址:http://wcf.codeplex.com/documentation 

    3. Open Rasta:OpenRasta是一个基于MIT协议开源的支持.NET 2.0以上的Rest开发框架,重点围绕这资源和HTTP方法开发的REST框架。文档地址:https://github.com/openrasta/openrasta-stable/wiki 

    4. Service Stack :是一个高性能的开源 .NET/Mono  REST服务框架 地址:http://www.servicestack.net/

    5. RestSharp :这只是一个支持WindowsPhone,Mono for Android, MonoTouch跨平台的Rest 客户端开发库。地址:http://restsharp.org/

作者: 自由、创新、研究、探索……
出处:http://shanyou.cnblogs.com/
版权:本文版权归作者和博客园共有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任 
原文地址:https://www.cnblogs.com/Leo_wl/p/2330272.html