2020年新年將至,先預祝.Net Core越來越好。 做了這麼多年一線開發,經常跟Http打交道。比如調用三方的Webservice,比如集成微信支付的時候服務端發起Prepay支付。特別是現在分散式、微服務大行其道,服務間通訊都離不開http調用。 多年前也造過幾個http client的小輪子 ...
2020年新年將至,先預祝.Net Core越來越好。
做了這麼多年一線開發,經常跟Http打交道。比如調用三方的Webservice,比如集成微信支付的時候服務端發起Prepay支付。特別是現在分散式、微服務大行其道,服務間通訊都離不開http調用。
多年前也造過幾個http client的小輪子。這次使用C#強大的擴展方法進行了重構,使代碼看起來有那麼一點流式編程的風格,再配合dynamic有點寫JavaScript的趕腳呢。今天拿出來分享給大家,為.Net Core的生態盡一點綿薄之力。
Github: https://github.com/kklldog/AgileHttp 歡迎star 。
安裝
Install-Package AgileHttp
示例
使用HTTP.Send方法
使用HTTP.Send / HTTP.SendAsync方法可以直接發送一個請求
HTTP.Send("http://www.baidu.com") // 預設為Get方法
HTTP.Send("http://www.baidu.com", "POST")
HTTP.Send("http://www.baidu.com", "POST", new { name = "mjzhou" })
HTTP.Send("http://www.baidu.com", "POST", new { name = "mjzhou" }, new RequestOptions { ContentType = "application/json" })
ResponseInfo response = HTTP.Send("http://localhost:5000/api/user/1");
string content = response.GetResponseContent(); //獲取http響應返回值的文本內容
HTTP.SendAsync方法是HTTP.Send方法的非同步版本
使用HttpClient類
如果不喜歡手寫"GET","POST","PUT"等HTTP方法,可以是使用HttpClient類。HttpClient類內置了GET,POST,PUT,DELETE,OPTIONS幾個常用的方法。
var client = new HttpClient("http://www.baidu.com");
client.Get();//使用HttpClient發送Get請求
var client = new HttpClient("http://www.baidu.com");
client.Config(new RequestOptions { ContentType = "application/json" });
client.Post(new { name = "mjzhou" }); //使用HttpClient發送Post請求
ResponseInfo response = new HttpClient("http://localhost:5000/api/user/1").Get();
string content = response.GetResponseContent(); //獲取http響應返回值的文本內容
User user1 = new HttpClient("http://localhost:5000/api/user/1").Get<User>(); //泛型方法可以直接反序列化成對象。
Get,Post等方法都有非同步版本GetAsync,PostAsync
使用擴展方法
C#強大的擴展方法可以讓寫代碼行雲流水。AgileHttp提供了幾個擴展方法,讓使用更人性化。
var result =
"http://localhost:5000/api/user"
.AppendQueryString("name", "kklldog")
.AsHttpClient()
.Get()
.GetResponseContent();
var user =
"http://localhost:5000/api/user"
.AppendQueryString("name", "kklldog")
.AsHttpClient()
.Get<User>();
- String.AppendQueryString
給一個字元串添加查詢參數
"http://localhost:5000/api/user".AppendQueryString("name", "mjzhou") // 返回結果為"http://localhost:5000/api/user?name=mjzhou"
- String.AppendQueryStrings
給一個字元串添加多個查詢參數
var qs = new Dictionary<string, object>();
qs.Add("a", "1");
qs.Add("b", "2");
"http://localhost:5000/api/user".AppendQueryStrings(qs) // 返回結果為"http://localhost:5000/api/user?a=1&b=2"
- String.AsHttp
以當前字元串為URL創建一個HttpRequest
"http://www.baidu.com".AsHttp().Send(); //預設為Get
"http://localhost:5000/api/user".AsHttp("POST", new { name = "mjzhou" }).Send();
- String.AsHttpClient
以當前字元串為URL創建一個HttpClient
"http://www.baidu.com".AsHttpClient().Get();
"http://localhost:5000/api/user".AsHttpClient().Post(new { name = "mjzhou" });
- ResponseInfo.Deserialize T
ResponseInfo是請求結果的包裝類,使用Deserialize方法可以直接反序列化成對象。如果沒有配置RequestOptions則使用預設SerializeProvider。
HTTP.Send("http://www.baidu.com").Deserialize<User>();
RequestOptions
使用RequestOptions可以對每個請求進行配置,比如設置ContentType,設置Headers,設置代理等等。
屬性 | 說明 |
---|---|
SerializeProvider | 獲取序列化器 |
Encoding | 獲取編碼方式 |
Headers | 獲取或設置HttpHeaders |
ContentType | 獲取或設置Http ContentType屬性 |
Host | 獲取或設置Http Host屬性 |
Connection | 獲取或設置Http Connection屬性 |
UserAgent | 獲取或設置Http UserAgent屬性 |
Accept | 獲取或設置Http Accept屬性 |
Referer | 獲取或設置Http Referer屬性 |
Certificate | 獲取或設置X509證書信息 |
Proxy | 獲取或設置代理信息 |
關於序列化/反序列化
當你使用Post,Put(不限於這2個方法)方法提交一個對象的時候AgileHttp會自動就行序列化。使用泛型Get T, Post T方法會自動進行反序列化。預設使用JsonSerializeProvider來進行序列化及反序列化。JsonSerializeProvider使用著名的Newtonsoft.Json實現了ISerializeProvider介面,如果你喜歡你也可以自己實現自己的Provider,比如實現一個XMLSerializeProvider。
public interface ISerializeProvider
{
T Deserialize<T>(string content);
string Serialize(object obj);
}
AgileHttp提供2個地方來修改SerializeProvider:
- 通過RequestOptions為單個Http請求配置序列化器
var xmlSerializeProvider = new xmlSerializeProvider();
var client = new HttpClient("http://www.baidu.com");
client.Config(new RequestOptions(xmlSerializeProvider));
- 通過HTTP.SetDefaultSerializeProvider(ISerializeProvider provider)更改全局預設序列化器
var xmlSerializeProvider = new xmlSerializeProvider();
HTTP.SetDefaultSerializeProvider(xmlSerializeProvider);
註意!:如果提交的body參數的類型為String或者byte[]不會進行再次序列化。