Надіслати повідомлення HTTP POST в ASP.NET Core за допомогою HttpClient PostAsJsonAsync


143

Я хочу надіслати динамічний об’єкт на кшталт

new { x = 1, y = 2 };

як тіло повідомлення HTTP POST. Тому я намагаюся писати

var client = new HttpClient();

але я не можу знайти метод

client.PostAsJsonAsync()

Тому я спробував додати пакет Microsoft.AspNetCore.Http.Extensions до project.json та додати

using Microsoft.AspNetCore.Http.Extensions; 

використовувати пункт Однак це мені не допомогло.

Отже, який найпростіший спосіб відправити POST-запит разом з тілом JSON в ASP.NET Core?


Цікаво, чому ця стаття не містить приклад для POST docs.microsoft.com/en-us/dotnet/csharp/tutorials/…
joym8

Відповіді:


206

Ви повинні додати посилання на пакет "Microsoft.AspNet.WebApi.Client" (прочитайте цю статтю для зразків).

Без додаткового розширення ви можете використовувати стандартний PostAsyncметод:

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

де jsonInStringзначення ви можете отримати, зателефонувавшиJsonConvert.SerializeObject(<your object>);


1
Але Microsoft.AspNet.WebApi.Client не схожий на ASP.NET Core RC2-бібліотеку. І шлях до дійсності - це занадто багато повторення коду ((
Rem

@Rem, чому б не створити HttpClient метод розширення ( PostAsJsonAsync), щоб використовувати другий спосіб. Це дозволяє уникнути повторення коду.
adem caglin

1
Звичайно. Але я поставив питання, щоб дізнатись, чи щось мені не вистачає. Я не можу повірити, що він ще не був реалізований в Core!
Рем

1
Ця бібліотека не є основною / .net-стандартною, я не думаю, що System.Net.Http.Форматинг ще був перенесений
Chris S

1
Це буде працювати для HttpClient, створеного IHttpClientFactory в .NET Core 2.2 з нульового пакету Microsoft.Extensions.Http. Однак як це зробити, але додайте заголовки, такі як ключ авторизації.
Нік

99

Я використовую цей клас:

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 }));

5
Чому б не метод розширення? публічний статичний клас JsonContent {public Task <?> PostAsJSonAsync (цей клієнт HttpClient, об'єкт toSerializeAsJson) {...}}
TamusJRoyce

2
Мені подобається підхід до класу JsonContent
Марко Алвеш

Чи встановлює цей Content-Length:заголовок HTTP?
В’ячеслав Нападовський

1
@VyacheslavNapadovsky, це залежить від HttpClientналаштувань, наприклад, якщо один client.DefaultRequestHeaders.TransferEncodingChunked = true Content-Lengthзаголовок набору не буде встановлений і Transfer-Encoding: chunkedбуде встановлений натомість. Однак якщо такий створений клієнт var client = new HttpClient();, заголовок Content-Lengthбуде встановлений для цього класу вмісту за замовчуванням.
стоп-

12

Я б додав до прийнятої відповіді, що ви також хочете додати Acceptзаголовок до httpClient:

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

так, мені це теж потрібно, підтверджене користуванням листоношею.
Вейхуй Го

1

Ви праві, що це вже давно реалізовано в .NET Core.

На момент написання (вересень 2019 року) project.jsonфайл NuGet 3.x + був замінений PackageReference(як пояснено на https://docs.microsoft.com/en-us/nuget/archive/project-json ).

Щоб отримати доступ до *Asyncметодів HttpClientкласу, ваш .csprojфайл повинен бути правильно налаштований.

Відкрийте .csprojфайл у текстовому редакторі та переконайтеся, що перший рядок
<Project Sdk="Microsoft.NET.Sdk.Web">
(як зазначено на https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj#the -csproj-формат ).

Щоб отримати доступ до *Asyncметодів HttpClientкласу, вам також потрібно мати у своєму файлі правильну посилання на пакет.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тепер повинні працювати з коробки. (Не потрібно використання директиви.)

Оновлення: Тег PackageReference більше не потрібен у .NET Core 3.0.


Не вдалося змусити PostAsJsonAsync працювати з .NET Core 3.1. Спасибі
Кріс Коленко
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.