【问题标题】:Send HTTP POST message in ASP.NET Core using HttpClient PostAsJsonAsync使用 HttpClient PostAsJsonAsync 在 ASP.NET Core 中发送 HTTP POST 消息
【发布时间】: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 请求的最简单方法是什么?

【问题讨论】:

标签: c# asp.net-core .net-core


【解决方案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

    【讨论】:

    【解决方案5】:

    如果您使用的是 .NET 5 或更高版本,则可以(并且应该)使用来自 System.Net.Http.JsonPostAsJsonAsync 扩展方法:

    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 文件,并确保第一行是
      &lt;Project Sdk="Microsoft.NET.Sdk.Web"&gt;
      (正如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)

      PostAsJsonAsyncReadAsAsyncPutAsJsonAsyncDeleteAsync 等方法现在应该可以开箱即用了。 (不需要 using 指令。)

      更新: .NET Core 3.0 不再需要 PackageReference 标记。

      【讨论】:

      • 我无法让 PostAsJsonAsync 与 .NET Core 3.1 一起使用。谢谢
      猜你喜欢
      • 1970-01-01
      • 2011-11-21
      • 1970-01-01
      • 1970-01-01
      • 2016-12-08
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      相关资源
      最近更新 更多