Отправить сообщение 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?

Rem
источник
Удивление , почему эта статья не содержит пример 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) для использования вторым способом. Это позволяет избежать повторения кода.
Адем Каглин
1
Конечно. Но я задал вопрос, чтобы узнать, что я что-то упустил. Я не могу поверить, что это еще не было реализовано в Core!
Рем
1
Эта библиотека не является базовой / .net-стандартной, я не думаю, что System.Net.Http.Formatting еще перенесен
Chris S
1
Это будет работать для HttpClient, созданного IHttpClientFactory в .NET Core 2.2 из пакета nuget 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 }));
стоп-Cran
источник
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. Спасибо
Крис Коленко