好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

RestSharp使用详解

RestSharp使用详解

  看了张善友老师的几篇文章后决定认真学习一下Restfull风格的API开发和调用,于是先选用了RestSharp 作为客户端进行练习。调用的服务为阿里巴巴提供的开放存储服务。

阿里巴巴云存储服务提供了50G的免费空间以及每个月10G的流量,非常适合我们做点小应用。具体的API规则请查阅 OSS存储服务开发文档 。

1、推荐的使用方式

直接上代码啦~

     public   class   AliyunApi
    {
          const   string  BaseUrl =  "  http://storage.aliyun测试数据  "  ;

          readonly   string   _accountSid;
          readonly   string   _secretKey;

          public  AliyunApi( string  accountSid,  string   secretKey)
        {
            _accountSid  =  accountSid;
            _secretKey  =  secretKey;
        }
          //  返回的XML或Josn对象直接反序列为实体对象 
         public  T Execute<T>(RestRequest request)  where  T :  new  ()
        {
              var  client =  new   RestClient();
            client.BaseUrl  =  BaseUrl;
            client.Authenticator  =  new   AliyunAuthenticator(_accountSid, _secretKey);

              string  date = DateTime.UtcNow.ToString( "  r  "  );
            request.AddHeader(Constants.DATE, date);
              var  response = client.Execute<T> (request);
              if  (( int )response.StatusCode /  100  !=  2  )
            {
                  throw   new   OssException(response);
            }
              return   response.Data;
        }
     //返回信息没有Body的对象
public IRestResponse Execute(RestRequest request) { var client = new RestClient(); client.BaseUrl = BaseUrl; client.Authenticator = new AliyunAuthenticator(_accountSid, _secretKey); string date = DateTime.UtcNow.ToString( " r " ); request.AddHeader(Constants.DATE, date); var response = client.Execute(request); if (( int )response.StatusCode / 100 != 2 ) { throw new OssException(response); } return response; } // 列出所有的Bucket public ListAllMyBucketsResult ListAllMyBuckets() { var request = new RestRequest(); request.Resource = " / " ; request.Method = Method.GET; // request.AddParameter("CallSid", callSid, ParameterType.UrlSegment); return Execute<ListAllMyBucketsResult> (request); }      //创建一个Bucket
public void PutBucket( string bucket, string per) { if (! Utils.ValidateBucketName(bucket)) { throw new ArgumentException( " Unsupported bucket name: " + bucket); } var request = new RestRequest(); request.Resource = " / " + bucket + " / " ; request.Method = Method.PUT; request.AddHeader(Constants.ACL, per); var response = Execute(request); } }

上面定义了两个Execute方法,一个可以返回泛型结果T一个用于没有返回实体对象操作的。下面分别定义了ListAllMyBuckets来列出我所创建的所有Bucket,PutBucket用于创建一个新的Bucket。

2、错误处理

细心的朋友一定注意到了返回错误的处理方式:

             if  (( int )response.StatusCode /  100  !=  2 )
            {
                 throw   new  OssException(response);
            }
在RestSharp的HttpResponse 类型中定义了两个有关Http状态的字段分别为:

1:System.Net.HttpStatusCode枚举类型的StatusCode

2:RestSharp.ResponseStatus枚举类型的ResponseStatus

除网络连接失败,DNS请求失败等原因ResponseStatus均为 Completed。

HttpStatusCode才是用来描述web服务器发回来的状态,也就是我们常说的200、301、404、500等http头。

System.Net.HttpStatusCode 在定义中关于200的一共有一下7种

        OK = 200,
        Created = 201,
        Accepted = 202,
        NonAuthoritativeInformation = 203,
        NoContent = 204,
        ResetContent = 205,
        PartialContent = 206,

也就是说200以内的都是成功的请求,因此单纯判断(response.StatusCode==HttpStatusCode.OK),可能出现意外。

3、自定义验证

自定义验证相对简单了,根据OSS文档要求就可以了代码如下:

  public   class   AliyunAuthenticator : IAuthenticator
    {
          private   const   string  DEFINE_PREFIX =  "  x-oss-  "  ;
          private   const   string  ALGORITHM =  "  HmacSHA1  "  ;

          private   readonly   string   accessKeyId;
          private   readonly   string   secretAccessKey;

          public  AliyunAuthenticator( string  accessKeyId,  string   secretAccessKey)
        {
              this .secretAccessKey =  secretAccessKey;
              this .accessKeyId =  accessKeyId;
        }
          public   void   Authenticate(IRestClient client, IRestRequest request)
        {
            IEnumerable <Parameter> headers = request.Parameters.Where(m => m.Type ==  ParameterType.HttpHeader);
            IDictionary < string ,  string > dHeaders =  new  Dictionary< string ,  string > ();

              foreach  (Parameter p  in   headers)
            {
                dHeaders.Add(p.Name, p.Value.ToString());
            }


              if  (! string .IsNullOrEmpty(secretAccessKey) && ! string  .IsNullOrEmpty(accessKeyId))
            {
                  string  resource =  request.Resource;
                  if (request.Resource.IndexOf( "  client.BaseUrl  " )> 0  )
                    resource  = request.Resource.Remove( 0  , client.BaseUrl.Length);
                  string  authValue =  "  OSS   " 
                     +  this  .accessKeyId
                      +  "  :  " 
                     +  GetAssign(secretAccessKey, request.Method.ToString(), dHeaders, resource);

                request.AddHeader(Constants.AUTHORIZATION, authValue);
            }
              else   if  (! string  .IsNullOrEmpty(accessKeyId))
            {
                request.AddHeader(Constants.AUTHORIZATION, accessKeyId);
            }
        }

          private   static   string  GetAssign( string  secretAccessKey,  string   method,
            IDictionary < string ,  string > headers,  string   resource)
        {
            StringBuilder canonicalizedOssHeaders  =  new   StringBuilder();
            StringBuilder stringToSign  =  new   StringBuilder();
              byte [] byteHMAC =  null  ;
              string  contentMd5 =  SafeGetElement(Constants.CONTENT_MD5, headers);
              string  contentType =  SafeGetElement(Constants.CONTENT_TYPE, headers);
              string  date =  SafeGetElement(Constants.DATE, headers);
              string  canonicalizedResource =  resource;


            SortedDictionary < string ,  string > tmpHeaders =  formatHeader(headers);
              if  (tmpHeaders.Count >  0  )
            {
                  foreach  ( string  key  in   tmpHeaders.Keys)
                {
                      if   (key.ToLower().StartsWith(DEFINE_PREFIX))
                    {
                        canonicalizedOssHeaders.Append(key).Append(  "  :  "  )
                                .Append(tmpHeaders[key]).Append(  "  \n  "  );
                    }
                }
            }
            stringToSign.Append(method).Append(  "  \n  "  ).Append(contentMd5)
                    .Append(  "  \n  " ).Append(contentType).Append( "  \n  "  ).Append(date)
                    .Append(  "  \n  "  ).Append(canonicalizedOssHeaders)
                    .Append(canonicalizedResource);
              try  
            {
                Encoding encoding  =  ASCIIEncoding.GetEncoding(Constants.CHARSET);
                  byte [] keyBytes =  encoding.GetBytes(secretAccessKey);
                KeyedHashAlgorithm hmac  =  KeyedHashAlgorithm.Create(ALGORITHM);
                hmac.Key  =  keyBytes;
                byteHMAC  =  hmac.ComputeHash(encoding.GetBytes(stringToSign.ToString()));
            }
              catch   (Exception e)
            {
            }
              return   Convert.ToBase64String(byteHMAC);
        }

          private   static  SortedDictionary< string ,  string >  formatHeader(
        IDictionary < string ,  string >  headers)
        {
            SortedDictionary < string ,  string > tmpHeaders =  new  SortedDictionary< string ,  string > ();

              foreach  ( string  key  in   headers.Keys)
            {
                  if   (key.ToLower().StartsWith(DEFINE_PREFIX))
                {
                    tmpHeaders[key.ToLower()]  =  headers[key];
                }
                  else  
                {
                    tmpHeaders[key]  =  headers[key];
                }
            }
              return   tmpHeaders;
        }

          private   static   string  SafeGetElement( string  key, IDictionary< string ,  string >  map)
        {
              if  (map ==  null  || ! map.ContainsKey(key))
            {
                  return   ""  ;
            }
              return   map[key];
        }
    } 

     public   class   AliyunAuthenticator : IAuthenticator
    {
          private   const   string  DEFINE_PREFIX =  "  x-oss-  "  ;
          private   const   string  ALGORITHM =  "  HmacSHA1  "  ;

          private   readonly   string   accessKeyId;
          private   readonly   string   secretAccessKey;

          public  AliyunAuthenticator( string  accessKeyId,  string   secretAccessKey)
        {
              this .secretAccessKey =  secretAccessKey;
              this .accessKeyId =  accessKeyId;
        }
          public   void   Authenticate(IRestClient client, IRestRequest request)
        {
            IEnumerable <Parameter> headers = request.Parameters.Where(m => m.Type ==  ParameterType.HttpHeader);
            IDictionary < string ,  string > dHeaders =  new  Dictionary< string ,  string > ();

              foreach  (Parameter p  in   headers)
            {
                dHeaders.Add(p.Name, p.Value.ToString());
            }


              if  (! string .IsNullOrEmpty(secretAccessKey) && ! string  .IsNullOrEmpty(accessKeyId))
            {
                  string  resource =  request.Resource;
                  if (request.Resource.IndexOf( "  client.BaseUrl  " )> 0  )
                    resource  = request.Resource.Remove( 0  , client.BaseUrl.Length);
                  string  authValue =  "  OSS   " 
                     +  this  .accessKeyId
                      +  "  :  " 
                     +  GetAssign(secretAccessKey, request.Method.ToString(), dHeaders, resource);

                request.AddHeader(Constants.AUTHORIZATION, authValue);
            }
              else   if  (! string  .IsNullOrEmpty(accessKeyId))
            {
                request.AddHeader(Constants.AUTHORIZATION, accessKeyId);
            }
        }

          private   static   string  GetAssign( string  secretAccessKey,  string   method,
            IDictionary < string ,  string > headers,  string   resource)
        {
            StringBuilder canonicalizedOssHeaders  =  new   StringBuilder();
            StringBuilder stringToSign  =  new   StringBuilder();
              byte [] byteHMAC =  null  ;
              string  contentMd5 =  SafeGetElement(Constants.CONTENT_MD5, headers);
              string  contentType =  SafeGetElement(Constants.CONTENT_TYPE, headers);
              string  date =  SafeGetElement(Constants.DATE, headers);
              string  canonicalizedResource =  resource;


            SortedDictionary < string ,  string > tmpHeaders =  formatHeader(headers);
              if  (tmpHeaders.Count >  0  )
            {
                  foreach  ( string  key  in   tmpHeaders.Keys)
                {
                      if   (key.ToLower().StartsWith(DEFINE_PREFIX))
                    {
                        canonicalizedOssHeaders.Append(key).Append(  "  :  "  )
                                .Append(tmpHeaders[key]).Append(  "  \n  "  );
                    }
                }
            }
            stringToSign.Append(method).Append(  "  \n  "  ).Append(contentMd5)
                    .Append(  "  \n  " ).Append(contentType).Append( "  \n  "  ).Append(date)
                    .Append(  "  \n  "  ).Append(canonicalizedOssHeaders)
                    .Append(canonicalizedResource);
              try  
            {
                Encoding encoding  =  ASCIIEncoding.GetEncoding(Constants.CHARSET);
                  byte [] keyBytes =  encoding.GetBytes(secretAccessKey);
                KeyedHashAlgorithm hmac  =  KeyedHashAlgorithm.Create(ALGORITHM);
                hmac.Key  =  keyBytes;
                byteHMAC  =  hmac.ComputeHash(encoding.GetBytes(stringToSign.ToString()));
            }
              catch   (Exception e)
            {
            }
              return   Convert.ToBase64String(byteHMAC);
        }

          private   static  SortedDictionary< string ,  string >  formatHeader(
        IDictionary < string ,  string >  headers)
        {
            SortedDictionary < string ,  string > tmpHeaders =  new  SortedDictionary< string ,  string > ();

              foreach  ( string  key  in   headers.Keys)
            {
                  if   (key.ToLower().StartsWith(DEFINE_PREFIX))
                {
                    tmpHeaders[key.ToLower()]  =  headers[key];
                }
                  else  
                {
                    tmpHeaders[key]  =  headers[key];
                }
            }
              return   tmpHeaders;
        }

          private   static   string  SafeGetElement( string  key, IDictionary< string ,  string >  map)
        {
              if  (map ==  null  || ! map.ContainsKey(key))
            {
                  return   ""  ;
            }
              return   map[key];
        }
    } 

上面只是把基本的结构分析了一下,看似简单,在应用过程中,遇到了很多麻烦。下一篇在分析使用过程中遇到的具体问题了,欢迎拍砖。

 

 

标签:  Restfull ,  阿里云

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

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

版权信息

查看更多关于RestSharp使用详解的详细内容...

  阅读:43次

上一篇: Service Locator

下一篇:XML 的简介与开发