翻译自: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