使用 System.Net.Http.Json 简化 HttpClient 的使用
Intro
从 .NET Core 3.1 开始,微软添加了一个 System.Net.Http.Json
的扩展,可以用来简化 HttpClient
的使用,看到在很多项目里还并未开始使用,所以想向大家介绍一下
Sample
PostAsJson/PutAsJson
PostAsJson
sample:
const string url = "http://localhost:5000/api/values";
using var httpClient = new HttpClient();
using var response = await httpClient.PostAsJsonAsync(url, new Category()
{
Id = 1,
Name = "Test"
});
response.EnsureSuccessStatusCode();
PutAsJson
:
using var response = await httpClient.PutAsJsonAsync(url, new Category()
{
Id = 1,
Name = "Test"
});
response.EnsureSuccessStatusCode();
简单来说就是会把一个对象变成 JSON request body
目前支持 Post 和 Put 方法 默认的序列化方式和 ASP.NET Core 是一致的,会变成 camalCase, 例如
如果要自定义序列化,可以传入一个 JsonSerializerOptions
,如:
using var response = await httpClient.PostAsJsonAsync(url, new Category()
{
Id = 1,
Name = "Test"
}, new JsonSerializerOptions());
response.EnsureSuccessStatusCode();
可以看到这个例子中的 body 和之前有所不同了,这正是因为我们使用了自定义的 JsonSerializerOptions
GetFromJsonAsync
var result = await httpClient.GetFromJsonAsync<ResultModel>(url);
ArgumentNullException.ThrowIfNull(result);
Console.WriteLine($"{result.Status}: {result.ErrorMsg}");
和上面的 AsJson
相对应,这个是从 Response body 到一个对象,同样地也支持自定义 JsonSerializerOptions
,可以自己尝试一下
ReadFromJsonAsync
using var response = await httpClient.PutAsJsonAsync(url, new Category()
{
Id = 1,
Name = "Test"
});
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<ResultModel>();
ArgumentNullException.ThrowIfNull(result);
Console.WriteLine($"{result.Status}: {result.ErrorMsg}");
直接从 HttpContent
中读取 json 对象
JsonContent.Create
using var content = JsonContent.Create(new Category() { Id = 1, Name = "Test" });
using var response = await httpClient.PostAsync(url, content);
response.EnsureSuccessStatusCode();
从一个对象构建 HttpContent
,同样支持自定义序列化
MoreSample
使用前后的一些对比:
More
JSON现在已经非常的普遍了,这一扩展可以使得 HttpClient 处理 JSON 更为简单,而且从 .NET 6 开始已经包含在了框架中,不需要再手动引用 nuget 包了
在 .NET 7 中会增加一个 PatchAsJsonAsync
的扩展方法,目前发布的 Preview 1 已经可用,使用方法类似于 PostAsJsonAsync
/PutAsJsonAsync
,HttpMethod 是 Patch
另外觉得应该有一个类似于 GetFromJsonAsync
的 DeleteFromJsonAsync
,提了一个 issue,感兴趣的可以关注一下:https://github.com/dotnet/runtime/issues/65617
如果返回的 response 状态码不是 2xx,
GetFromJsonAsync
会抛异常,如果是不合法的 JSON 也会抛出异常
References
https://github.com/dotnet/runtime/issues/65617
https://github.com/dotnet/runtime/tree/main/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json
https://github.com/WeihanLi/SamplesInPractice/blob/master/HttpClientTest/JsonExtensionSample.cs
https://github.com/OpenReservation/ReservationServer/commit/d07f9dc5ae292dd748d7f7a879898009c198d70d