今天有空,小结一下RestSharp的用法。
RestSharp内置了XML和JSON的反序列化(deserializers )。
- application/json – JsonDeserializer
- application/xml – XmlDeserializer
- text/json – JsonDeserializer
- text/xml – XmlDeserializer
- * – XmlDeserializer (all other content types not specified)
比如下面的实体类:
Public class Employee {
Public string EmployeeId {get; set ;}
Public int EmployeeName {get; set ;}
Public int EmployeeAge {get ; set ;}
}
对应的XML:
<Employee>
< EmployeeId >1< /EmployeeId >
< EmployeeName>John</ EmployeeName>
< EmployeeAge>30</ EmployeeAge>
<Employee>
对应的JSON:
{
EmployeeId:1
EmployeeName:”John”
EmployeeAge:30
}
1. 异步调用
client.ExecuteAsync(request, response => {
Console.WriteLine(response.Content);
});
2. 实现接口IRestAPIExecutor
using RestSharp;
using System;
using System.Threading.Tasks;
namespace myCompany
{
public class RestAPIExecutor : IRestAPIExecutor
{
public string BaseUrl { get; set; }
public string DefaultDateParameterFormat { get; set; }
public IAuthenticator DefaultAuthenticator { get; set; }
private RestClient client;
public RestAPIExecutor(string CmsBaseURI, IAuthenticator Authenticator = null, string DateParameterFormat = null)
{
BaseUrl = CmsBaseURI;
DefaultAuthenticator = Authenticator;
client = new RestClient();
if (DefaultAuthenticator != null)
client.Authenticator = DefaultAuthenticator;
if (DateParameterFormat != null)
DefaultDateParameterFormat = DateParameterFormat;
client.BaseUrl = BaseUrl;
}
public T GenericExecute<T>(RestRequest request) where T : new()
{
request.DateFormat = string.IsNullOrEmpty(DefaultDateParameterFormat) ? "yyyy-MM-dd HH:mm:ss" : DefaultDateParameterFormat;
var response = client.Execute<T>(request);
if (response.ErrorException != null)
{
throw new RestCallException("Error retrieving response. Check inner details for more info.", response.ErrorException);
}
return response.Data;
}
public RestRequestAsyncHandle AsyncGenericExecute<T>(RestRequest request, Action<IRestResponse<T>> action) where T : new()
{
request.DateFormat = string.IsNullOrEmpty(DefaultDateParameterFormat) ? "yyyy-MM-dd HH:mm:ss" : DefaultDateParameterFormat;
return client.ExecuteAsync<T>(request, action);
}
public Task<T> GetTaskAsync<T>(RestRequest request) where T : new()
{
request.DateFormat = string.IsNullOrEmpty(DefaultDateParameterFormat) ? "yyyy-MM-dd HH:mm:ss" : DefaultDateParameterFormat;
return client.GetTaskAsync<T>(request);
}
public IRestResponse Execute(RestRequest request)
{
request.DateFormat = string.IsNullOrEmpty(DefaultDateParameterFormat) ? "yyyy-MM-dd HH:mm:ss" : DefaultDateParameterFormat;
var response = client.Execute(request);
if (response.ErrorException != null)
{
throw new RestCallException("Error retrieving response. Check inner details for more info.", response.ErrorException);
}
return response;
}
public byte[] DownloadData(RestRequest request)
{
return client.DownloadData(request);
}
}
}
3. 实现自己的业务逻辑,包括
- HTTP GET,返回JSON,自动反序列化为实体类
- HTTP GET,获得返回的XML字符串,并转为XDocument
- 获得返回的http header里面的字段
- HTTP POST, 提交一个zip包
- HTTP GET, Partial download, 分段下载大的内容,可能包含很多个请求。最后还需要另外发一个请求获得整个文件的SHA码
using System.Xml.Linq;
using RestSharp;
using System;
using System.Configuration;
using System.IO;
using System.Linq;
namespace myCompany
{
public class myClient
{
#region Initialization
private readonly IRestAPIExecutor restAPIExecutor;
public myClient()
{
restAPIExecutor = new RestAPIExecutor(ConfigurationManager.AppSettings[Utility.Constants.Configuration.CmsBaseUri],
DateParameterFormat: ConfigurationManager.AppSettings[Utility.Constants.Configuration.DateFormat]);
}
public myClient(string CmsBaseURI, string dateFormat, string username = null, string password = null)
{
restAPIExecutor = !string.IsNullOrEmpty(username) ? new RestAPIExecutor(CmsBaseURI, DateParameterFormat: dateFormat, Authenticator: new HttpBasicAuthenticator(username, password)) : new RestAPIExecutor(CmsBaseURI, DateParameterFormat: dateFormat);
}
#endregion
//HTTP GET,返回JSON,自动反序列化为实体类
public OrderResult GetOrders(DateTime date, string channel = null, string merchant = null, string venue = null)
{
var request = new RestRequest(ConfigurationManager.AppSettings[Utility.Constants.Configuration.API_Campaign_List], Method.GET);
request.AddParameter("date", string.Format("{0:yyyy-MM-dd}", date));
if (!string.IsNullOrEmpty(channel)) request.AddParameter("channel", channel);
if (!string.IsNullOrEmpty(merchant)) request.AddParameter("merchant", merchant);
if (!string.IsNullOrEmpty(venue)) request.AddParameter("venue", venue);
return restAPIExecutor.GenericExecute<OrderResult>(request);
}
//HTTP GET,获得返回的XML字符串,并转为XDocument
public XDocument GetOrderDetailsXml(int OrderID)
{
var request = new RestRequest(ConfigurationManager.AppSettings[Utility.Constants.Configuration.API_Order_Details], Method.GET);
request.AddHeader(Application.AcceptHttpHeader, Application.AcceptHttpHeaderValue);
request.AddParameter("OrderID", OrderID.ToString(), ParameterType.UrlSegment);
var response = restAPIExecutor.Execute(request);
//获得返回的http header里面的字段
//var sha = response.Headers.Where(s => s.Name == Application.SHAHttpHeader).Select(s => s.Value).FirstOrDefault();
return XDocument.Parse(response.Content);
}
//HTTP POST, 提交一个zip包
public IRestResponse UploadZipFile(string fileName, byte[] fileContent)
{
var request = new RestRequest(ConfigurationManager.AppSettings[Utility.Constants.Configuration.API_POP_ZIP_Upload], Method.POST);
request.AddHeader("Content-Type", "application/zip");
request.AddParameter("filename", fileName);
request.AddFile("gzip", fileContent, fileName, "application/zip");
return restAPIExecutor.Execute(request);
}
//HTTP GET, Partial download, 分段下载大的内容,可能包含很多个请求。最后还需要另外发一个请求获得整个文件的SHA码
public byte[] DownloadPartialOrderMedia()
{
var request = new RestRequest(ConfigurationManager.AppSettings[Utility.Constants.Configuration.API_POP_ZIP_Upload], Method.POST);
request.AddParameter("filename", fileName);
return restAPIExecutor.DownloadData(request);
}
}
}
3. 异步读取RESTful API
var client = new RestClient("http://example.org");
var request = new RestRequest("product/42", Method.GET);
var content = await client.GetContentAsync(request);
扩展方法:
using System;
using System.Threading.Tasks;
using RestSharp;
namespace RestSharpEx
{
public static class RestClientExtensions
{
private static Task<T> SelectAsync<T>(this RestClient client, IRestRequest request, Func<IRestResponse, T> selector)
{
var tcs = new TaskCompletionSource<T>();
var loginResponse = client.ExecuteAsync(request, r =>
{
if (r.ErrorException == null)
{
tcs.SetResult(selector(r));
}
else
{
tcs.SetException(r.ErrorException);
}
});
return tcs.Task;
}
public static Task<string> GetContentAsync(this RestClient client, IRestRequest request)
{
return client.SelectAsync(request, r => r.Content);
}
public static Task<IRestResponse> GetResponseAsync(this RestClient client, IRestRequest request)
{
return client.SelectAsync(request, r => r);
}
}
}