为 zijian666.HttpClientExtensions 扩展 json和动态类型支持
$ dotnet add package zijian666.HttpClientExtensions.Convert扩展原生HttpClient,HttpMessageHandler,HttpResponseMessage等;
以最优雅,最便捷的方式调用HTTP接口。
利用.NET扩展方法的语法糖,扩展.NET原生对象;
最大程度的避免对原有代码的污染,也方便与其他第三方组件库联动。
nuget - zijian666.HttpClientExtensions
nuget - zijian666.HttpClientExtensions.Convert
var s = http.Fluent()
.BaseUrl("https://api.apiopen.top")
.Path("getJoke")
.Query(new
{
page = 1,
count = 2,
type = "video"
})
.GetString();
// .GetStringAsync(); -- await/async
由于一步操作返回的都是只读结构体
readonly struct FluentHttpClient,
所以你可以在任何时间将它保存起来,
而不必担心后续操作会改变其中的值。
[TestMethod]
public void PathTemplateTest()
{
var obj = new
{
id = 1,
name = "zijian666",
time = "2020-10-17 16:14:23",
array = new[] { 1, 2, 3, 4, }
};
using var client = new HttpClient();
var url = client.Fluent()
.BaseUrl("baidu.com/a/b/c")
.Path("user/{id}/name={name}/{array}/{time}", obj)
.ToString("url");
Assert.AreEqual("http://baidu.com/a/b/user/1/name=zijian666/1,2,3,4/2020-10-17%2016:14:23", url);
}
using var client = new HttpClient();
var file = Directory.GetFiles("d:\\")
.Select(x => new FileInfo(x))
.First(x => x.Length > 10240 && x.Length < 100 * 1024);
var raw = client.Fluent()
.BaseUrl("baidu.com")
.Path("image/upload")
.AddDefaultHeaders()
.Form(
new FormData("str", "test.jpg"),
new FormData("bytes", new byte[] { 111, 222, 123 }, "ok.db"),
new FormData("file", new FileInfo("d:\\1.jpg"), "image/jpg")
)
.SendAsync();
上传文件支持
Stram,byte[],FileInfo,前2种最好提供文件名;
不过即使没有文件名,提交时也会使用默认文件名"stream"和"bytes"。
安装 zijian666.HttpClientExtensions.Convert 实现
json和动态类型dynamic的支持
var obj = new
{
id = 1,
name = "zijian666",
time = "2020-10-17 16:14:23",
array = new[] { 1, 2, 3, 4, }
};
using var client = new HttpClient();
var raw = client.Fluent()
.BaseUrl("baidu.com")
.Path("get/user")
.AddDefaultHeaders()
.JsonBody(obj)
.ToString();
Console.WriteLine(raw);
GET http://baidu.com/get/user 1.1
Content-Type: application/json; charset=utf-8
User-Agent: .NET-Framework/3.1.8,(Microsoft Windows NT 10.0.19041.0; WOW64),zijian666.HttpClientExtensions/1.0.0.0,(BLQW-XIAOMIGTX; blqw)
Accept: */*
Accept-Encoding: gzip,deflate
Accept-Language: zh-CN,zh; q=0.8
{"id":1,"name":"zijian666","time":"2020-10-17 16:14:23","array":[1,2,3,4]}using var http = new HttpClient();
var s = http.Fluent()
.BaseUrl("https://api.apiopen.top")
.Path("getJoke")
.Query(new
{
page = 1,
count = 2,
type = "video"
})
.GetDynamic();
Console.WriteLine(s);
Console.WriteLine($"code = {s.code}");
Console.WriteLine($"message = {s.message}");{"code":200,"message":"\u6210\u529F!","result":[{"sid":"31568775","text":"\u8FFD\u94F6\u884C\u5C0F\u59D0\u59D0\u5168\u8FC7\u7A0B\uFF0C\u770B\u4EBA\u5BB6\u662F\u600E\u4E48\u8FFD\u5973\u5B69\u7684\u3002","type":"video","thumbnail":"http://wimg.spriteapp.cn/picture/2020/0903/84bbafce-ed8f-11ea-8969-1866daeb0df0_wpd.jpg","video":"http://uvideo.spriteapp.cn/video/2020/0903/84bbafce-ed8f-11ea-8969-1866daeb0df0_wpd.mp4","images":{},"up":"396","down":"12","forward":"18","comment":"27","uid":"22904192","name":"\u767E\u601D\u7206\u7B11","header":"http://wimg.spriteapp.cn/profile/20180809175405412650.jpg","top_comments_content":{},"top_comments_voiceuri":{},"top_comments_uid":{},"top_comments_name":{},"top_comments_header":{},"passtime":"2020-09-17 21:10:05"},{"sid":"31568566","text":"\u5144\u5F1F\u4EEC\uFF0C\u600E\u4E48\u628A\u6211\u7684\u804C\u4E1A\u8BF4\u5F97\u9AD8\u7AEF\u4E00\u4E9B\uFF1F","type":"video","thumbnail":"http://wimg.spriteapp.cn/picture/2020/0902/d39a6c04-ecc5-11ea-ac6c-1866daeb0df0_wpd.jpg","video":"http://uvideo.spriteapp.cn/video/2020/0902/d39a6c04-ecc5-11ea-ac6c-1866daeb0df0_wpd.mp4","images":{},"up":"277","down":"3","forward":"10","comment":"27","uid":"20620899","name":"\u9047\u4E00\u72D7\u767D\u9996","header":"http://wimg.spriteapp.cn/profile/20190318103732351696.jpeg","top_comments_content":"\u795E\u519C","top_comments_voiceuri":"","top_comments_uid":"22956417","top_comments_name":"\u5468\u6B63\u6D0B","top_comments_header":"http://wimg.spriteapp.cn/profile","passtime":"2020-09-17 21:00:05"}]}
code = 200
message = 成功!阅读 FluentHttpClient 和 HttpClientExtensions 你也可以很轻松的写出扩展方法。
参考:
public static FluentHttpClient AddDefaultHeaders(this FluentHttpClient fluent)
{
return fluent.DefaultHeader("Accept", "*/*")
.DefaultHeader("Accept-Encoding", "gzip, deflate")
.DefaultHeader("Accept-Language", "zh-CN,zh;q=0.8");
}
public static Task<string> GetStringAsync(this FluentHttpClient fluent)
=> fluent.Method("Get").SendAsync().ReadAsStringAsync();