使用 HttpClient PostAsJsonAsync 在 ASP.NET Core 中发送 HTTP POST 消息
Send HTTP POST message in ASP.NET Core using HttpClient PostAsJsonAsync
我想发送像这样的动态对象
new { x = 1, y = 2 };
作为 HTTP POST 消息的正文。所以我试着写
var client = new HttpClient();
但是我找不到方法
client.PostAsJsonAsync()
所以我尝试将 Microsoft.AspNetCore.Http.Extensions 包添加到 project.json 并添加
using Microsoft.AspNetCore.Http.Extensions;
使用子句。但是它对我没有帮助。
那么在 ASP.NET 核心中发送带有 JSON 主体的 POST 请求的最简单方法是什么?
您应该添加对 "Microsoft.AspNet.WebApi.Client" 包的引用(阅读 this article 获取样本)。
无需任何附加扩展,您可以使用标准 PostAsync
方法:
client.PostAsync(uri, new StringContent(jsonInString, Encoding.UTF8, "application/json"));
其中 jsonInString
您可以通过调用 JsonConvert.SerializeObject(<your object>);
获得的值
我会在接受的答案中添加您还想将 Accept
header 添加到 httpClient
:
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
我用这个class:
public class JsonContent : StringContent
{
public JsonContent(object obj) :
base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json")
{ }
}
用法示例:
new HttpClient().PostAsync("http://...", new JsonContent(new { x = 1, y = 2 }));
你是对的,这早就在 .NET Core 中实现了。
在撰写本文时(2019 年 9 月),NuGet 3.x+ 的 project.json
文件已被 PackageReference
取代(如 https://docs.microsoft.com/en-us/nuget/archive/project-json 所述)。
要访问 HttpClient
class 的 *Async
方法,您的 .csproj
文件必须正确配置。
在纯文本编辑器中打开 .csproj
文件,确保第一行是
<Project Sdk="Microsoft.NET.Sdk.Web">
(正如 https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj#the-csproj-format 指出的那样)。
要访问 HttpClient
class 的 *Async
方法,您还需要在您的 包参考 .csproj
文件,像这样:
<ItemGroup>
<!-- ... -->
<PackageReference Include="Microsoft.AspNetCore.App" />
<!-- ... -->
</ItemGroup>
(参见 https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference。
另外:我们建议应用程序以 ASP.NET Core 2.1 为目标,之后使用 Microsoft.AspNetCore.App 元包、https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage)
PostAsJsonAsync
、ReadAsAsync
、PutAsJsonAsync
和 DeleteAsync
等方法现在应该开箱即用。 (不需要使用指令。)
更新: .NET Core 3.0 不再需要 PackageReference 标签。
Microsoft 现在建议使用 IHttpClientFactory
具有以下优势:
- 为命名和配置逻辑提供了一个中心位置
HttpClient
个实例。例如,名为 github 的客户端可以是
已注册并配置为访问 GitHub。默认客户端可以是
已注册一般访问权。
- 通过委托处理程序整理传出中间件的概念
在
HttpClient
。为 Polly-based 中间件提供扩展
在 HttpClient
. 中委派处理程序的优势
- 管理基础资产池和生命周期
HttpClientMessageHandler
个实例。自动管理避免
手动操作时出现的常见 DNS(域名系统)问题
管理 HttpClient
生命周期。
- 为所有请求添加可配置的日志记录体验(通过
ILogger
)
通过工厂创建的客户端发送。
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1
设置:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
// Remaining code deleted for brevity.
POST 例子:
public class BasicUsageModel : PageModel
{
private readonly IHttpClientFactory _clientFactory;
public BasicUsageModel(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task CreateItemAsync(TodoItem todoItem)
{
var todoItemJson = new StringContent(
JsonSerializer.Serialize(todoItem, _jsonSerializerOptions),
Encoding.UTF8,
"application/json");
var httpClient = _clientFactory.CreateClient();
using var httpResponse =
await httpClient.PostAsync("/api/TodoItems", todoItemJson);
httpResponse.EnsureSuccessStatusCode();
}
如果您使用的是 .NET 5 或更高版本,您可以(并且应该)使用 System.Net.Http.Json 中的 PostAsJsonAsync
扩展方法:
httpClient.PostAsJsonAsync(url, new {
x = 1,
y = 2
});
如果您使用的是旧版本的.NET Core,您可以自行实现扩展功能:
public static class HttpClientExtensions
{
public static Task<HttpResponseMessage> PostJsonAsync(this HttpClient httpClient, string url, object body)
{
var bodyJson = JsonSerializer.Serialize(body);
var stringContent = new StringContent(bodyJson, Encoding.UTF8, "application/json");
return httpClient.PostAsync(url, stringContent);
}
}
我想发送像这样的动态对象
new { x = 1, y = 2 };
作为 HTTP POST 消息的正文。所以我试着写
var client = new HttpClient();
但是我找不到方法
client.PostAsJsonAsync()
所以我尝试将 Microsoft.AspNetCore.Http.Extensions 包添加到 project.json 并添加
using Microsoft.AspNetCore.Http.Extensions;
使用子句。但是它对我没有帮助。
那么在 ASP.NET 核心中发送带有 JSON 主体的 POST 请求的最简单方法是什么?
您应该添加对 "Microsoft.AspNet.WebApi.Client" 包的引用(阅读 this article 获取样本)。
无需任何附加扩展,您可以使用标准 PostAsync
方法:
client.PostAsync(uri, new StringContent(jsonInString, Encoding.UTF8, "application/json"));
其中 jsonInString
您可以通过调用 JsonConvert.SerializeObject(<your object>);
我会在接受的答案中添加您还想将 Accept
header 添加到 httpClient
:
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
我用这个class:
public class JsonContent : StringContent
{
public JsonContent(object obj) :
base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json")
{ }
}
用法示例:
new HttpClient().PostAsync("http://...", new JsonContent(new { x = 1, y = 2 }));
你是对的,这早就在 .NET Core 中实现了。
在撰写本文时(2019 年 9 月),NuGet 3.x+ 的 project.json
文件已被 PackageReference
取代(如 https://docs.microsoft.com/en-us/nuget/archive/project-json 所述)。
要访问 HttpClient
class 的 *Async
方法,您的 .csproj
文件必须正确配置。
在纯文本编辑器中打开 .csproj
文件,确保第一行是
<Project Sdk="Microsoft.NET.Sdk.Web">
(正如 https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj#the-csproj-format 指出的那样)。
要访问 HttpClient
class 的 *Async
方法,您还需要在您的 包参考 .csproj
文件,像这样:
<ItemGroup>
<!-- ... -->
<PackageReference Include="Microsoft.AspNetCore.App" />
<!-- ... -->
</ItemGroup>
(参见 https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference。 另外:我们建议应用程序以 ASP.NET Core 2.1 为目标,之后使用 Microsoft.AspNetCore.App 元包、https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage)
PostAsJsonAsync
、ReadAsAsync
、PutAsJsonAsync
和 DeleteAsync
等方法现在应该开箱即用。 (不需要使用指令。)
更新: .NET Core 3.0 不再需要 PackageReference 标签。
Microsoft 现在建议使用 IHttpClientFactory
具有以下优势:
- 为命名和配置逻辑提供了一个中心位置
HttpClient
个实例。例如,名为 github 的客户端可以是 已注册并配置为访问 GitHub。默认客户端可以是 已注册一般访问权。 - 通过委托处理程序整理传出中间件的概念
在
HttpClient
。为 Polly-based 中间件提供扩展 在HttpClient
. 中委派处理程序的优势
- 管理基础资产池和生命周期
HttpClientMessageHandler
个实例。自动管理避免 手动操作时出现的常见 DNS(域名系统)问题 管理HttpClient
生命周期。 - 为所有请求添加可配置的日志记录体验(通过
ILogger
) 通过工厂创建的客户端发送。
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1
设置:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
// Remaining code deleted for brevity.
POST 例子:
public class BasicUsageModel : PageModel
{
private readonly IHttpClientFactory _clientFactory;
public BasicUsageModel(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task CreateItemAsync(TodoItem todoItem)
{
var todoItemJson = new StringContent(
JsonSerializer.Serialize(todoItem, _jsonSerializerOptions),
Encoding.UTF8,
"application/json");
var httpClient = _clientFactory.CreateClient();
using var httpResponse =
await httpClient.PostAsync("/api/TodoItems", todoItemJson);
httpResponse.EnsureSuccessStatusCode();
}
如果您使用的是 .NET 5 或更高版本,您可以(并且应该)使用 System.Net.Http.Json 中的 PostAsJsonAsync
扩展方法:
httpClient.PostAsJsonAsync(url, new {
x = 1,
y = 2
});
如果您使用的是旧版本的.NET Core,您可以自行实现扩展功能:
public static class HttpClientExtensions
{
public static Task<HttpResponseMessage> PostJsonAsync(this HttpClient httpClient, string url, object body)
{
var bodyJson = JsonSerializer.Serialize(body);
var stringContent = new StringContent(bodyJson, Encoding.UTF8, "application/json");
return httpClient.PostAsync(url, stringContent);
}
}