Gửi tin nhắn HTTP POST trong ASP.NET Core bằng cách sử dụng HttpClient PostAsJsonAsync


142

Tôi muốn gửi đối tượng động như

new { x = 1, y = 2 };

như phần thân của thông điệp HTTP POST. Vì vậy tôi cố gắng viết

var client = new HttpClient();

nhưng tôi không thể tìm ra phương pháp

client.PostAsJsonAsync()

Vì vậy, tôi đã cố gắng thêm gói Microsoft.AspNetCore.Http.Extensions vào project.json và thêm

using Microsoft.AspNetCore.Http.Extensions; 

để sử dụng mệnh đề. Tuy nhiên nó không giúp tôi.

Vậy cách dễ nhất để gửi yêu cầu POST với phần thân JSON trong ASP.NET Core là gì?


Tự hỏi tại sao bài viết này không chứa ví dụ cho POST docs.microsoft.com/en-us/dotnet/csharp/tutorials/ trộm
joym8

Câu trả lời:


205

Bạn nên thêm tham chiếu đến gói "Microsoft.AspNet.WebApi.Client" (đọc bài viết này để lấy mẫu).

Nếu không có bất kỳ tiện ích mở rộng bổ sung nào, bạn có thể sử dụng PostAsyncphương pháp tiêu chuẩn :

client.PostAsync(uri, new StringContent(jsonInString, Encoding.UTF8, "application/json"));

nơi jsonInStringbạn có thể nhận được giá trị bằng cách gọiJsonConvert.SerializeObject(<your object>);


1
Nhưng Microsoft.AspNet.WebApi.Client không giống thư viện ASP.NET Core RC2. Và cách thức secon thực sự là quá nhiều sự lặp lại mã ((
Rem

@Rem tại sao bạn không tạo HttpClient phương thức mở rộng ( PostAsJsonAsync) để sử dụng cách thứ hai. Nó cho phép bạn tránh lặp lại mã.
adem caglin

1
Chắc chắn rồi. Nhưng tôi đã hỏi câu hỏi để tìm hiểu xem tôi có thiếu thứ gì không. Tôi không thể tin rằng nó chưa được triển khai trong Core!
Rem

1
Thư viện này không phải là thư viện lõi / .net, tôi không nghĩ System.Net.Http.Formatted đã được chuyển
Chris S

1
Điều này sẽ hoạt động cho HttpClient được tạo bởi IHttpClientFactory trong .NET Core 2.2 từ gói nuget Microsoft.Extensions.Http. Tuy nhiên, làm thế nào để bạn làm theo cách này nhưng thêm các tiêu đề như khóa ủy quyền.
Nick Gallolas

98

Tôi sử dụng lớp này:

public class JsonContent : StringContent
{
    public JsonContent(object obj) :
        base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json")
    { }
}

Mẫu sử dụng:

new HttpClient().PostAsync("http://...", new JsonContent(new { x = 1, y = 2 }));

5
Tại sao không phải là một phương pháp mở rộng? lớp tĩnh công khai JsonContent {Nhiệm vụ công cộng <?> PostAsJSonAsync (ứng dụng khách HTTPClient này, đối tượng đểSerializeAsJson) {...}}
TamusJRoyce

2
Tôi thích cách tiếp cận của lớp JsonContent
Marco Alves

Cái này có đặt Content-Length:tiêu đề HTTP không?
Vyacheslav Napadovsky

1
@VyacheslavNapadovsky, nó phụ thuộc vào HttpClientcài đặt, ví dụ: nếu một client.DefaultRequestHeaders.TransferEncodingChunked = true Content-Lengthtiêu đề được đặt sẽ không được đặt và Transfer-Encoding: chunkedthay vào đó sẽ được đặt. Tuy nhiên, nếu một người tạo ứng dụng khách như thế var client = new HttpClient();, tiêu đề Content-Lengthsẽ được đặt cho lớp nội dung này theo mặc định.
stop-cran

12

Tôi sẽ thêm vào câu trả lời được chấp nhận rằng bạn cũng muốn thêm Accepttiêu đề vào httpClient:

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

vâng, với tôi điều này cũng được yêu cầu, được xác nhận bằng cách sử dụng người đưa thư.
Quách Weihui

1

Bạn đúng rằng điều này đã được triển khai từ lâu trong .NET Core.

Tại thời điểm viết (tháng 9 năm 2019), project.jsontệp của NuGet 3.x + đã được thay thế bởi PackageReference(như được giải thích tại https://docs.microsoft.com/en-us/nuget/archive/project-json ).

Để có quyền truy cập vào các *Asyncphương thức của HttpClientlớp, .csprojtệp của bạn phải được cấu hình chính xác.

Mở .csprojtệp của bạn trong trình soạn thảo văn bản đơn giản và đảm bảo dòng đầu tiên là
<Project Sdk="Microsoft.NET.Sdk.Web">
(như được chỉ ra tại https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj#the -csproj-định dạng ).

Để có quyền truy cập vào các *Asyncphương thức của HttpClientlớp, bạn cũng cần phải có tham chiếu gói chính xác trong .csprojtệp của mình , như vậy:

<ItemGroup>
    <!-- ... -->
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <!-- ... -->
</ItemGroup>

(Xem https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference . Ngoài ra: Chúng tôi khuyên dùng các ứng dụng nhắm mục tiêu ASP.NET Core 2.1 và sau đó sử dụng siêu dữ liệu Microsoft.AspNetCore.App , https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage )

Các phương pháp như PostAsJsonAsync, ReadAsAsync, PutAsJsonAsyncDeleteAsyncbây giờ sẽ làm việc ra khỏi hộp. (Không sử dụng chỉ thị cần thiết.)

Cập nhật: Thẻ PackageReference không còn cần thiết trong .NET Core 3.0.


Tôi không thể quản lý để PostAsJsonAsync hoạt động với .NET Core 3.1. Cảm ơn
Chris Kolenko
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.