RestSharp使用說明

翻譯自:https://github.com/restsharp/RestSharp/wiki,轉載請註明。git

##1、新手入門##github

若是隻有少許一次性請求須要封裝爲API,則能夠以下使用RestSharp :json

using RestSharp;
using RestSharp.Authenticators;

var client = new RestClient();
client.BaseUrl = new Uri("http://twitter.com");
client.Authenticator = new HttpBasicAuthenticator("username", "password");

var request = new RestRequest();
request.Resource = "statuses/friends_timeline.xml";

IRestResponse response = client.Execute(request);

IRestResponse 接口中包含了全部遠程服務返回的信息,能夠訪問頭信息(header)數據內容(content)、HTTP狀態等。建議使用泛型將返回結果自動反序列化爲.NET實體類。c#

關於錯誤處理:api

若是發生了網絡傳輸錯誤(網絡癱瘓,DNS查找失敗等),RestResponse.ResponseStatus 將會置爲Error ,不然RestResponse.ResponseStatus的值爲Completed 。若是API返回404,ResponseStatus 仍然是Completed 。若是須要訪問返回的HTTP狀態碼,則須要查看RestResponse.StatusCode 的值,Status  屬性是請求完成的標識,獨立於API錯誤處理。數組

##2、推薦用法##緩存

RestSharp適合做爲API代理類實現的基礎,下面是 Twilio類庫中的一些使用示例:服務器

建立一個包含API代理實現的類,聲明一個執行方法看成全部請求的入口。這個執行方法容許設置經常使用參數和其它跨請求共享設置(例如認證),由於每個請求都須要賬戶ID和密鑰,因此在創建新的代理實例時都須要傳遞這兩個值。須要注意的是執行過程當中不會拋出異常,可是能夠在ErrorException 中訪問到異常信息。cookie

// TwilioApi.cs
public class TwilioApi {
    const string BaseUrl = "https://api.twilio.com/2008-08-01";

    readonly string _accountSid;
    readonly string _secretKey;

    public TwilioApi(string accountSid, string secretKey) {
        _accountSid = accountSid;
        _secretKey = secretKey;
    }

    public T Execute<T>(RestRequest request) where T : new()
    {
        var client = new RestClient();
        client.BaseUrl = new System.Uri(BaseUrl);
        client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
        request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment); // used on every request
        var response = client.Execute<T>(request);

        if (response.ErrorException != null)
        {
            const string message = "Error retrieving response.  Check inner details for more info.";
            var twilioException = new ApplicationException(message, response.ErrorException);
            throw twilioException;
        }
        return response.Data;
    }

}

接下來,定義一個實體類來映射API返回的數據,再定義一個方法用來訪問API同時獲取返回的Call資源的具體信息:網絡

// Call.cs
public class Call
{
    public string Sid { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateUpdated { get; set; }
    public string CallSegmentSid { get; set; }
    public string AccountSid { get; set; }
    public string Called { get; set; }
    public string Caller { get; set; }
    public string PhoneNumberSid { get; set; }
    public int Status { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public int Duration { get; set; }
    public decimal Price { get; set; }
    public int Flags { get; set; }
}

// TwilioApi.cs, method of TwilioApi class
public Call GetCall(string callSid) 
{
    var request = new RestRequest();
    request.Resource = "Accounts/{AccountSid}/Calls/{CallSid}";
    request.RootElement = "Call";

    request.AddParameter("CallSid", callSid, ParameterType.UrlSegment);

    return Execute<Call>(request);
}

有一些神奇之處是RestSharp 須要關心而咱們沒必要關注:

一、API返回的XML數據被默認XmlDeserializer 檢測到,同時反序列化爲Call對象。

二、默認RestRequest 對應HTTP中的GET 請求,能夠經過設置RestRequest  的Method屬性或者在建立請求實例時經過構造函數指定Method  類型來改變請求類型。

三、UrlSegment  類型參數會根據Resource 屬性值中匹配的名稱標籤將值注入到URL中,AccountSid  在 TwilioApi.Execute  賦值,對於每個請求它都是相同的。

四、咱們指定了從哪裏開始反序列化的根元素名稱,在本例中,返回的XML形如<Response><Call>...</Call></Response> ,由於Response元素不包含與咱們定義的實體模型相關的任何信息,因此從元素樹的下一個節點開始反序列化(Call節點)。

咱們還能夠定義POST(和 PUT/DELETE/HEAD/OPTIONS )請求:

// TwilioApi.cs, method of TwilioApi class
public Call InitiateOutboundCall(CallOptions options) 
{
    Require.Argument("Caller", options.Caller);
    Require.Argument("Called", options.Called);
    Require.Argument("Url", options.Url);

    var request = new RestRequest(Method.POST);
    request.Resource = "Accounts/{AccountSid}/Calls";
    request.RootElement = "Calls";

    request.AddParameter("Caller", options.Caller);
    request.AddParameter("Called", options.Called);
    request.AddParameter("Url", options.Url);

    if (options.Method.HasValue) request.AddParameter("Method", options.Method);
    if (options.SendDigits.HasValue()) request.AddParameter("SendDigits", options.SendDigits);
    if (options.IfMachine.HasValue) request.AddParameter("IfMachine", options.IfMachine.Value);
    if (options.Timeout.HasValue) request.AddParameter("Timeout", options.Timeout.Value);

    return Execute<Call>(request);
}

本示例一樣證實RestSharp是一個輕量級驗證助手,能夠在請求前先校驗提交的參數值是否有效。

示例中經過AddParameter  方法添加的參數值將經過標準編碼格式提交,相似於經過網頁提交的表單。若是是GET形式的請求(GET/DELETE/OPTIONS/HEAD) ,參數值將經過查詢字符串提交,AddParameter() 方法也能夠添加頭信息和cookie 參數。將一個對象的全部屬性做爲參數時,使用AddObject() 方法。上傳一個文件時用 AddFile() 方法(請求會以多種編碼格式發送),當請求中包含請求體時(例如XML或者JSON),用AddBody()方法。

##3、其它應用示例##

下面的示例演示了用流(stream)代替內存緩衝請求內容,這在請求大量數據同時須要馬上寫入磁盤的場景下很是有用:

string tempFile = Path.GetTempFileName();
using (var writer = File.OpenWrite(tempFile))
{
    var client = new RestClient(baseUrl);
    var request = new RestRequest("Assets/LargeFile.7z");
    request.ResponseWriter = (responseStream) => responseStream.CopyTo(writer);
    var response = client.DownloadData(request);
}

##4、反序列化##

RestSharp擁有處理XML和JSON的反序列化器,當收到響應時,RestClient經過服務器返回的Content Type 選擇適合的反序列化器。默認設置能夠經過自定義設置的Content Type覆蓋,支持的Content Type以下:

  • application/json - JsonDeserializer
  • application/xml - XmlDeserializer
  • text/json - JsonDeserializer
  • text/xml - XmlDeserializer
  • *+json - JsonDeserializer (content types using a Structured Suffix Syntax specifying JSON)
  • *+xml - XmlDeserializer (content types using a Structured Suffix Syntax specifying XML)
  • @*@ - XmlDeserializer (all other content types not specified)

默認的反序列化器嘗試解除必須解析XML或者JSON的痛苦,經過映射CLR實體類來實現。實體類定義瞭如何反序列化返回的數據。RestSharp再也不採用遍歷返回的數據,再從實體類中查找匹配的屬性的方式反序列化數據,而是把實體類看成起點,循環遍歷可訪問的可寫屬性,同時在返回的數據中查找相應的元素。

注意:默認的反序列化器不支持 DataAnnotation/DataMember ,若是要使用,必須實現和註冊本身的IDeserializer ,IDeserializer 是包裝了與實體類中屬性兼容的反序列化庫。

例以下面的XML和JSON:

<Person>
    <Name>John</Name>
    <Id>28</Id>
</Person>

{
    "Name": "John",
    "Id": 28
}

映射相同的實體類Person:

public class Person 
{
    public string Name { get; set; }
    public int Id { get; set; }
}

###支持的屬性類型(數據類型):###

####XmlDeserializer:####

  • Primitives (int, short, long, etc)
  • Decimal
  • DateTime
  • String
  • Guid
  • List<T>
  • Nested classes
  • Nullable versions of the above listed types

####JsonDeserializer####

  • Primitives
  • Decimal
  • DateTime
  • String
  • Guid
  • List
  • Dictionary<T1, T2>
  • Nested classes
  • Nullable versions of the above listed types

###名稱匹配:###

####XmlDeserializer####

當查找匹配元素時,默認的XML反序列化器查找元素和特性遵循如下順序:

  • 元素和名稱絕對匹配
  • 元素和名稱的小寫匹配
  • 元素和名稱的駱駝命名匹配
  • 元素和名稱去掉下劃線和破折號匹配
  • 特性和名稱絕對匹配
  • 特性和名稱的小寫匹配
  • 特性和名稱的駱駝命名匹配
  • 特性和名稱去掉下劃線和破折號匹配

可使用@DeserializeAs@ 特性來更改將在屬性中查找的名稱,若是要將屬性的命名與XML中的名稱同,這一點將很是有用。

例如:

[DeserializeAs(Name = "forecast_information")]
public ForecastInformation Forecast { get; set; }

有一種返回元素值的特殊狀況,示例以下:

若是返回的XML數據以下:

<Response>Hello world</Response>

沒有辦法用c#的類直接描述

public class Response 
{
}

須要一些東西來保存返回的元素值,在本例中,添加一個Value屬性:

public class Response
{
     public string Value { get; set; }
}

####JsonDeserializer####

當爲匹配元素查找數據時,默認的JSON反序列化器在查找元素時將遵循如下順序:

  • 與名稱絕對匹配
  • 與名稱駱駝命名匹配
  • 與名稱小寫匹配
  • 與名稱加了下劃線匹配 (e.g. ProductId -> Product_Id)
  • 與名稱加了下劃線小寫形式匹配 (e.g. Product_id -> product_id)

XML反序列化器能夠經過設置屬性的DeserializeAs  特性來改變如何與JSON的鍵映射。

例如:

[DeserializeAs(Name = "forecast_information")]
public ForecastInformation Forecast { get; set; }

###集合處理(List/Dictionary)###

####XmlDeserializer####

處理兩種不一樣形式的集合:內聯和嵌套

<?xml version="1.0" encoding="utf-8" ?>
<InlineListSample>
    <image src="1.gif">value1</image>
    <image src="2.gif">value2</image>
    <image src="3.gif">value3</image>
    <image src="4.gif">value4</image>
</InlineListSample>

<?xml version="1.0" encoding="utf-8" ?>
<NestedListSample>
   <images>
      <image src="1.gif">value1</image>
      <image src="2.gif">value2</image>
      <image src="3.gif">value3</image>
      <image src="4.gif">value4</image>
    </images>
</NestedListSample>

對應的c#形式以下:

public class ListSample
{
    public List<Image> Images { get; set; }
}
    
public class Image
{
    public string Src { get; set; }
    public string Value { get; set; }
}

若是在同一份文檔中兩種元素結構恰巧同時存在,優先級按此順序:parented/nested/regular 。

####JsonDeserializer####

在映射JSON數組和字典時,RestSharp支持集合(List)和字典(Dictionary<string, T> )

###日期處理###

####XmlDeserializer####

  • 若是RestRequest.DateFormat已經指定了返回值的格式,則返回值使用指定格式字符串解析。
  • 若是 RestRequest.DateFormat 沒有指定, 用DateTime.Parse計算元素值. 若是該方法沒法處理當前格式, 則須要改變屬性類型爲String而後再進行處理 。

####JsonDeserializer####

若是沒有經過RestRequest.DateFormat指定日期格式,RestSharp嘗試用如下格式字符轉來反序列化DateTime類型的屬性(順序以下):

  • "u"
  • "s"
  • "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
  • "yyyy-MM-ddTHH:mm:ssZ"
  • "yyyy-MM-dd HH:mm:ssZ"
  • "yyyy-MM-ddTHH:mm:ss"
  • "yyyy-MM-ddTHH:mm:sszzzzzz"

JsonSerializer  默認支持如下JSON日期格式,若是指定了具體的RestRequest.DateFormat ,則默認被忽略:

  • ISO - 1910-09-25T09:30:25Z
  • Javascript Date Objects - new Date(-1870352975000)
  • Unix Timestamps - 1435206458

對於JS日期對象,在JS紀元時間基礎上加毫秒級的時間間隔,根據指定的時區調整。

###自定義###

####重寫默認反序列化器####

能夠經過以下步驟重寫本身的反序列化器處理返回的數據內:

  • 建立一個類同時實現IDeserializer接口。
  • 用RestClient.AddHandler(contentType, IDeserializer)方法註冊handler並關聯content類型,若是此content類型已經被註冊過,則會被指定的剛剛指定的handker重寫,能夠經過 RestClient.ClearHandlers()方法移除全部註冊的handler,或者經過RestClient.RemoveHandler(contentType)移除某一個handler。

####重寫默認的序列化器####

當使用XML或者JSON格式數據做爲請求體時,可使用本身實現的ISerializer  :

var request = new RestRequest();
request.RequestFormat = DataFormat.Xml;
request.XmlSerializer = new SuperXmlSerializer(); // implements ISerializer
request.AddBody(person); // object serialized to XML using your custom serializer;

####重寫JsonSerializationStrategy####

序列化過程當中,嘗試支持c#和JSOM間不一樣投影策略將會陷入麻煩,重寫MapClrMemberNameToJsonFieldName 將會有幫助:

class SnakeJsonSerializerStrategy : PocoJsonSerializerStrategy
{
    protected override string MapClrMemberNameToJsonFieldName(string clrPropertyName)
    {
        //PascalCase to snake_case
        return string.Concat(clrPropertyName.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + char.ToLower(x).ToString() : x.ToString()));
    }
}

而後在代碼中使用:

SimpleJson.CurrentJsonSerializerStrategy = new SnakeJsonSerializerStrategy();

##5、認證##

RestSharp包含HTTP認證,能夠經過IAuthenticator  完成本身的實現同時用RestClient註冊:

var client = new RestClient();
client.Authenticator = new SuperAuthenticator(); // implements IAuthenticator

在使用RestClient.Execute 或 RestClient.Execute<T> 方法時,驗證者的驗證方法首先被調用。

###使用SimpleAuthenticator###

SimpleAuthenticator 容許把用戶名和密碼看成GET 或 POST參數傳遞,具體取決於所使用的請求方法:

var client = new RestClient("http://example.com");
client.Authenticator = new SimpleAuthenticator("username", "foo", "password", "bar");

var request = new RestRequest("resource", Method.GET);
client.Execute(request);

請求生成的URL應該是以下形式:http://example.com/resource?username=foo&password=bar

上述請求若是使用PUT或者POST請求時,將會以編碼表單形式提交值。

##6、RestRequest的參數類型##

新建了RestRequest 後,能夠爲它添加參數,下面是5種當前支持的參數類型以及其在使用默認IHttp實現下的特性描述。

###Cookie###

添加到cookies  列表的參數將會隨着請求被單獨發送,Cookie名稱是參數的名稱,值則是傳遞的參數的值(.ToString )。

###HttpHeader###

添加做爲 HTTP header 的參數會隨着請求被單獨發送,Header名稱是參數的名稱,Header值則是傳遞的參數的值。

注意有些受限制的headers表現不一樣或者會被忽略,能夠在Http.cs中的_restrictedHeaderActions  字典中查看它們的特性。

###GetOrPost###

若是執行GET請求,RestSharp將會追加參數到URL中,形式以下:「url?name1=value1&name2=value2」 ;

若是是POST或者是PUT請求,則取決於請求中是否有文件,若是沒有,則參數以請求體發送,形如「name1=value1&name2=value2」 ,將會以application/x-www-form-urlencoded格式發送,基於不一樣的請求方法會有不一樣的表現。

兩種情形下,參數名稱和值都會自動被url編碼。

若是請求中有文件,RestSharp將會發送multipart/form-data 形式的請求,發送的參數將會形如如下格式:

Content-Disposition: form-data; name="parameterName"

ParameterValue

###UrlSegment###

不一樣於GetOrPost ,這種參數類型在RequestUrl 中用佔位符代替值。

var request = new RestRequest("health/{entity}/status");
request.AddParameter("entity", "s2", ParameterType.UrlSegment);

當執行請求時,RestSharp將嘗試用參數名稱匹配佔位符,匹配成功後則用參數值代替佔位符,上面的代碼結果是:「health/s2/status」  。

###RequestBody###

若是設置了這個參數,參數值會以請求的body方式傳遞。請求只能接收一個RequestBody  參數(第一個)。

參數名稱將被用做請求的Content-Type header 。

RequestBody  參數對於GET或者HEAD  是無效的,它們不須要發送請求體。

若是同時還有GetOrPost  參數,則該參數將重寫RequestBody  ——RestSharp  不會合並這些參數,但會拋棄RequestBody  參數。

###QueryString###

相似於GetOrPost ,除此以外,它老是用以下形式追加參數到URL:「url?name1=value1&name2=value2」 ,不論是什麼類型的請求方法。

##7、緩存##

###自動緩存管理###

RestSharp 102.4 +版本支持全部IRestClient 實例的請求共享同一個System.Net.CookieContainer 管理,經過這種方式,responses 設置或沒設置緩存在後續的請求中都會使用,爲了共享CookieContainer ,在建立RestClient 時設置屬性便可:

var client = new RestClient("http://server/");
client.CookieContainer = new System.Net.CookieContainer();

##8、跨平臺支持##

RestSharp包含2個版本的lib:

  • .NET Framework 4.5.2
  • .NET Standard 2.0

意味着能夠在如下平臺應用RestSharp:

  • Windows using .NET Framework
  • Windows using .NET Core
  • Linux or Mac using Mono
  • Linux or Mac using .NET Core
  • Any other platform that supports Mono 5 or .NET Core 2
相關文章
相關標籤/搜索