使用 HttpClient PostAsJsonAsync 在 ASP.NET Core 中发送 HTTP POST 消息
Posted
技术标签:
【中文标题】使用 HttpClient PostAsJsonAsync 在 ASP.NET Core 中发送 HTTP POST 消息【英文标题】:Send HTTP POST message in ASP.NET Core using HttpClient PostAsJsonAsync 【发布时间】:2016-06-10 14:12:11 【问题描述】:我想发送动态对象
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 Core 中使用 JSON 正文发送 POST 请求的最简单方法是什么?
【问题讨论】:
想知道为什么这篇文章不包含 POST docs.microsoft.com/en-us/dotnet/csharp/tutorials/… 的示例 【参考方案1】:您应该添加对“Microsoft.AspNet.WebApi.Client”包的引用(请阅读this article 以获取示例)。
无需任何额外扩展,您可以使用标准的PostAsync
方法:
client.PostAsync(uri, new StringContent(jsonInString, Encoding.UTF8, "application/json"));
你可以通过调用JsonConvert.SerializeObject(<your object>);
获得jsonInString
的值
【讨论】:
但是 Microsoft.AspNet.WebApi.Client 看起来不像 ASP.NET Core RC2 库。而第二种方式真的是代码重复太多了(( @Rem 你为什么不创建一个HttpClient
扩展方法(PostAsJsonAsync
)来使用第二种方式。它使您可以避免代码重复。
当然。但我问了这个问题,以便找出我是否遗漏了什么。我不敢相信它还没有在 Core 中实现!
这个库不是核心/.net 标准库,我认为 System.Net.Http.Formatting 还没有被移植
这适用于 .NET Core 2.2 中的 IHttpClientFactory 从 nuget 包 Microsoft.Extensions.Http 创建的 HttpClient。但是,您如何做到这一点,但添加诸如授权密钥之类的标头。【参考方案2】:
我使用这个类:
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 ));
【讨论】:
为什么不用扩展方法? public static class JsonContent public Task> PostAsJSonAsync(this HttpClient client, object toSerializeAsJson) ... 我喜欢 JsonContent 类方法 这是否设置了Content-Length:
HTTP 标头?
@VyacheslavNapadovsky 它取决于HttpClient
设置,例如如果一组client.DefaultRequestHeaders.TransferEncodingChunked = true
Content-Length
标题不会被设置,而Transfer-Encoding: chunked
将被设置。但是,如果创建像var client = new HttpClient();
这样的客户端,则默认情况下会为此内容类设置标题Content-Length
。【参考方案3】:
我将添加到已接受的答案中,您还希望将 Accept
标头添加到 httpClient
:
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
【讨论】:
【参考方案4】:Microsoft 现在建议使用 IHttpClientFactory
具有以下好处:
HttpClient
实例。例如,一个名为 github 的客户端可能是
注册并配置为访问 GitHub。默认客户端可以是
注册了一般访问权限。
通过委托处理程序编码传出中间件的概念
在HttpClient
。为基于 Polly 的中间件提供扩展以采用
在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();
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1#make-post-put-and-delete-requests
【讨论】:
_jsonSerializerOptions
部分是什么?你知道是否需要设置任何选项吗?
@Lukas 请参见此处:docs.microsoft.com/en-us/dotnet/standard/serialization/… Microsoft 在他们的示例代码中包含它,但尝试不使用它,看看会发生什么。 :)【参考方案5】:
如果您使用的是 .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);
【讨论】:
【参考方案6】:你说得对,这早就在 .NET Core 中实现了。
在撰写本文时(2019 年 9 月),NuGet 3.x+ 的 project.json
文件已被 PackageReference
取代(如 https://docs.microsoft.com/en-us/nuget/archive/project-json 所述)。
要访问HttpClient
类的*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
类的*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
等方法现在应该可以开箱即用了。 (不需要 using 指令。)
更新: .NET Core 3.0 不再需要 PackageReference 标记。
【讨论】:
我无法让 PostAsJsonAsync 与 .NET Core 3.1 一起使用。谢谢以上是关于使用 HttpClient PostAsJsonAsync 在 ASP.NET Core 中发送 HTTP POST 消息的主要内容,如果未能解决你的问题,请参考以下文章