RestSharp使用说明

RestSharp使用说明

翻译自: https://github.com/restsharp/RestSharp/wiki ,转载请注明。

一、新手入门

如果只有少量一次性请求需要封装为API,则可以如下使用RestSharp :

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实体类。

关于错误处理:

如果发生了网络传输错误(网络瘫痪,DNS查找失败等),RestResponse.ResponseStatus 将会置为Error ,否则RestResponse.ResponseStatus的值为Completed 。如果API返回404,ResponseStatus 仍然是Completed 。如果需要访问返回的HTTP状态码,则需要查看RestResponse.StatusCode 的值,Status 属性是请求完成的标识,独立于API错误处理。

二、推荐用法

RestSharp适合作为API代理类实现的基础,下面是 Twilio类库中的一些使用示例:

创建一个包含API代理实现的类,声明一个执行方法当作所有请求的入口。这个执行方法允许设置常用参数和其它跨请求共享设置(例如认证),因为每一个请求都需要帐户ID和密钥,所以在建立新的代理实例时都需要传递这两个值。需要注意的是执行过程中不会抛出异常,但是可以在ErrorException 中访问到异常信息。

// 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(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(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(request);

}

有一些神奇之处是RestSharp 需要关心而我们不必关注:

1、API返回的XML数据被默认XmlDeserializer 检测到,同时反序列化为Call对象。

2、默认RestRequest 对应HTTP中的GET 请求,可以通过设置RestRequest 的Method属性或者在创建请求实例时通过构造函数指定Method 类型来改变请求类型。

3、UrlSegment 类型参数会根据Resource 属性值中匹配的名称标签将值注入到URL中,AccountSid 在 TwilioApi.Execute 赋值,对于每一个请求它都是相同的。

4、我们指定了从哪里开始反序列化的根元素名称,在本例中,返回的XML形如... ,因为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(request);

}

本示例同样证明RestSharp是一个轻量级验证助手,可以在请求前先校验提交的参数值是否有效。

示例中通过AddParameter 方法添加的参数值将通过标准编码格式提交,类似于通过网页提交的表单。如果是GET形式的请求(GET/DELETE/OPTIONS/HEAD) ,参数值将通过查询字符串提交,AddParameter() 方法也可以添加头信息和cookie 参数。将一个对象的所有属性作为参数时,使用AddObject() 方法。上传一个文件时用 AddFile() 方法(请求会以多种编码格式发送),当请求中包含请求体时(例如XML或者JSON),用AddBody()方法。

三、其它应用示例

下面的示例演示了用流(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);

}

四、反序列化

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:

John

28

{

"Name": "John",

"Id": 28

}

映射相同的实体类Person:

public class Person

{

public string Name { get; set; }

public int Id { get; et; }

}

支持的属性类型(数据类型):

XmlDeserializer:

Primitives (int, short, long, etc)

Decimal

DateTime

String

Guid

List

Nested classes

Nullable versions of the above listed types

JsonDeserializer

Primitives

Decimal

DateTime

String

Guid

List

Dictionary

Nested classes

Nullable versions of the above listed types

名称匹配:

XmlDeserializer

当查找匹配元素时,默认的XML反序列化器查找元素和特性遵循以下顺序:

元素和名称绝对匹配

元素和名称的小写匹配

元素和名称的骆驼命名匹配

元素和名称去掉下划线和破折号匹配

特性和名称绝对匹配

特性和名称的小写匹配

特性和名称的骆驼命名匹配

特性和名称去掉下划线和破折号匹配

可以使用@DeserializeAs@ 特性来更改将在属性中查找的名称,如果要将属性的命名与XML中的名称同,这一点将非常有用。

例如:

[DeserializeAs(Name = "forecast_information")]

public ForecastInformation Forecast { get; set; }

有一种返回元素值的特殊情况,示例如下:

如果返回的XML数据如下:

Hello world

没有办法用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

处理两种不同形式的集合:内联和嵌套

value1

value2

value3

value4

value1

value2

value3

value4

对应的c#形式如下:

public class ListSample

{

public List Images { get; set; }

}

public class Image

{

public string Src { get; set; }

public string Value { get; set; }

}

如果在同一份文档中两种元素结构恰巧同时存在,优先级按此顺序:parented/nested/regular 。

JsonDeserializer

在映射JSON数组和字典时,RestSharp支持集合(List)和字典(Dictionary

日期处理

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();

五、认证

RestSharp包含HTTP认证,可以通过IAuthenticator 完成自己的实现同时用RestClient注册:

var client = new RestClient();

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

在使用RestClient.Execute 或 RestClient.Execute 方法时,验证者的验证方法首先被调用。

使用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请求时,将会以编码表单形式提交值。

六、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” ,不管是什么类型的请求方法。

七、缓存

自动缓存管理

RestSharp 102.4 +版本支持所有IRestClient 实例的请求共享同一个System.Net.CookieContainer 管理,通过这种方式,responses 设置或没设置缓存在后续的请求中都会使用,为了共享CookieContainer ,在创建RestClient 时设置属性即可:

var client = new RestClient("http://server/");

client.CookieContainer = new System.Net.CookieContainer();

八、跨平台支持

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

相关推荐

华为24年财报公布:有惊喜也有隐患,华为实现了不赚钱卖给大家!孟晚舟女士今天发布了华为24年的财报,有很大惊喜,但也发现...
各位卡级大佬,怎么掉经验比较快!
365bet手机app下载

各位卡级大佬,怎么掉经验比较快!

📅 01-30 👁️ 4991
原来鲍鱼还藏了这么多秘密?
365bet手机app下载

原来鲍鱼还藏了这么多秘密?

📅 11-27 👁️ 3209