Enviar mensagem HTTP POST no ASP.NET Core usando HttpClient PostAsJsonAsync

143

Eu quero enviar objetos dinâmicos como

new { x = 1, y = 2 };

como corpo da mensagem HTTP POST. Então eu tento escrever

var client = new HttpClient();

mas não consigo encontrar o método

client.PostAsJsonAsync()

Tentei adicionar o pacote Microsoft.AspNetCore.Http.Extensions ao project.json e adicionar

using Microsoft.AspNetCore.Http.Extensions; 

usa a cláusula No entanto, não me ajudou.

Então, qual é a maneira mais fácil de enviar solicitação POST com o corpo JSON no ASP.NET Core?

Rem
fonte
Gostaria de
saber

Respostas:

206

Você deve adicionar referência ao pacote "Microsoft.AspNet.WebApi.Client" (leia este artigo para obter exemplos).

Sem nenhuma extensão adicional, você pode usar o PostAsyncmétodo padrão :

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

onde o jsonInStringvalor que você pode obter chamandoJsonConvert.SerializeObject(<your object>);

Conjunto
fonte
1
Mas o Microsoft.AspNet.WebApi.Client não se parece com a biblioteca ASP.NET Core RC2. E a segunda maneira é realmente muito repetição de código ((
Rem
@Rem Por que você não cria um HttpClient método de extensão ( PostAsJsonAsync) para usar a segunda maneira. Permite evitar a repetição de código.
Adem caglin
1
Certo. Mas fiz a pergunta para descobrir se estou perdendo alguma coisa. Não acredito que ainda não foi implementado no Core!
Rem
1
Esta biblioteca não é um core / um .net-padrão, eu não acho que System.Net.Http.Formatting ainda não foi portado
Chris S
1
Isso funcionará para o HttpClient criado por IHttpClientFactory no .NET Core 2.2 a partir do pacote de pepitas Microsoft.Extensions.Http. No entanto, como você faz dessa maneira, mas adiciona cabeçalhos como uma chave de autorização.
Nick Gallimore
98

Eu uso esta classe:

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

Amostra de uso:

new HttpClient().PostAsync("http://...", new JsonContent(new { x = 1, y = 2 }));
stop-cran
fonte
5
Por que não um método de extensão? classe estática pública JsonContent {public Task <?> PostAsJSonAsync (este cliente HttpClient, objeto toSerializeAsJson) {...}}
TamusJRoyce
2
Eu gosto da abordagem de classe JsonContent
Marco Alves
Isso define o Content-Length:cabeçalho HTTP?
Vyacheslav Napadovsky
1
@VyacheslavNapadovsky, depende das HttpClientconfigurações, por exemplo, se um client.DefaultRequestHeaders.TransferEncodingChunked = true Content-Lengthcabeçalho de conjunto não for definido e Transfer-Encoding: chunked, em vez disso, será definido. No entanto, se alguém criar o cliente como var client = new HttpClient();, o cabeçalho Content-Lengthserá definido para esta classe de conteúdo por padrão.
stop-cran
12

Eu acrescentaria à resposta aceita que você também desejaria adicionar o Acceptcabeçalho ao httpClient:

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Serj Sagan
fonte
Sim, para mim isso também é necessário, confirmado usando o carteiro.
Weihui Guo
1

Você está certo de que isso há muito tempo foi implementado no .NET Core.

No momento da redação deste artigo (setembro de 2019), o project.jsonarquivo do NuGet 3.x + foi substituído PackageReference(conforme explicado em https://docs.microsoft.com/en-us/nuget/archive/project-json ).

Para obter acesso aos *Asyncmétodos da HttpClientclasse, seu .csprojarquivo deve estar configurado corretamente.

Abra seu .csprojarquivo em um editor de texto sem formatação e verifique se a primeira linha está
<Project Sdk="Microsoft.NET.Sdk.Web">
(conforme indicado em https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj#the -csproj-format ).

Para obter acesso aos *Asyncmétodos da HttpClientclasse, você também precisa ter a referência correta do pacote em seu .csprojarquivo, da seguinte maneira:

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

(Consulte https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference . Além disso: recomendamos aplicativos direcionados ao ASP.NET Core 2.1 e posteriormente use o metapacote Microsoft.AspNetCore.App , https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage )

Métodos como PostAsJsonAsync, ReadAsAsync, PutAsJsonAsynce DeleteAsyncagora deve funcionar fora da caixa. (Nenhuma diretiva de uso é necessária.)

Atualização: a marca PackageReference não é mais necessária no .NET Core 3.0.

Henke
fonte
Não consegui fazer o PostAsJsonAsync funcionar com o .NET Core 3.1. Obrigado
Chris Kolenko 20/02