Kirim pesan HTTP POST di ASP.NET Core menggunakan HttpClient PostAsJsonAsync

151

Saya ingin mengirim objek dinamis seperti

new { x = 1, y = 2 };

sebagai isi pesan HTTP POST. Jadi saya mencoba menulis

var client = new HttpClient();

tetapi saya tidak dapat menemukan metode

client.PostAsJsonAsync()

Jadi saya mencoba menambahkan paket Microsoft.AspNetCore.Http.Extensions ke project.json dan menambahkan

using Microsoft.AspNetCore.Http.Extensions; 

menggunakan klausa. Namun itu tidak membantu saya.

Jadi apa cara termudah untuk mengirim permintaan POST dengan tubuh JSON di ASP.NET Core?

Rem
sumber
Bertanya-tanya mengapa artikel ini tidak berisi contoh untuk POST docs.microsoft.com/en-us/dotnet/csharp/tutorials/…
joym8

Jawaban:

222

Anda harus menambahkan referensi ke paket "Microsoft.AspNet.WebApi.Client" (baca artikel ini untuk mengetahui contoh).

Tanpa ekstensi tambahan, Anda dapat menggunakan PostAsyncmetode standar :

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

di mana jsonInStringnilai yang bisa Anda dapatkan dengan meneleponJsonConvert.SerializeObject(<your object>);

Set
sumber
1
Tetapi Microsoft.AspNet.WebApi.Client tidak terlihat seperti pustaka ASP.NET Core RC2. Dan cara kedua adalah terlalu banyak pengulangan kode ((
Rem
1
@Rem mengapa Anda tidak membuat HttpClient metode ekstensi ( PostAsJsonAsync) untuk menggunakan cara kedua. Ini memungkinkan Anda untuk menghindari pengulangan kode.
adem caglin
1
Tentu. Tetapi saya mengajukan pertanyaan untuk mengetahui apakah saya melewatkan sesuatu. Saya tidak percaya ini belum diterapkan di Core!
Rem
1
Library ini bukan inti / .net-standar, saya rasa System.Net.Http.Formatting belum di-porting
Chris S
1
Ini akan bekerja untuk HttpClient yang dibuat oleh IHttpClientFactory di .NET Core 2.2 dari paket nuget Microsoft.Extensions.Http. Namun, bagaimana Anda melakukannya dengan cara ini tetapi menambahkan header seperti kunci otorisasi.
Nick Gallimore
104

Saya menggunakan kelas ini:

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

Contoh penggunaan:

new HttpClient().PostAsync("http://...", new JsonContent(new { x = 1, y = 2 }));
stop-cran
sumber
5
Mengapa bukan metode ekstensi? public static class JsonContent {public Task <?> PostAsJSonAsync (klien HttpClient ini, objek toSerializeAsJson) {...}}
TamusJRoyce
2
Saya suka pendekatan kelas JsonContent
Marco Alves
Apakah ini mengatur Content-Length:header HTTP?
Vyacheslav Napadovsky
1
@VyacheslavNapadovsky itu tergantung pada HttpClientpengaturan, misalnya jika satu set client.DefaultRequestHeaders.TransferEncodingChunked = true Content-Lengthheader tidak akan ditetapkan dan Transfer-Encoding: chunkedakan ditetapkan sebagai gantinya. Namun, jika seseorang membuat klien seperti itu var client = new HttpClient();, header Content-Lengthakan disetel untuk kelas konten ini secara default.
stop-cran
12

Saya akan menambahkan jawaban yang diterima bahwa Anda juga ingin menambahkan Accepttajuk ke httpClient:

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Serj Sagan
sumber
2

Microsoft sekarang merekomendasikan penggunaan IHttpClientFactorydengan manfaat berikut:

  • Menyediakan lokasi pusat untuk penamaan dan konfigurasi HttpClientinstance logis . Misalnya, klien bernama github dapat didaftarkan dan dikonfigurasi untuk mengakses GitHub. Klien default dapat didaftarkan untuk akses umum.
  • Mengkodifikasi konsep middleware keluar melalui penangan pendelegasian di HttpClient. Menyediakan ekstensi untuk middleware berbasis Polly untuk memanfaatkan pendelegasian penangan dalam HttpClient.
  • Mengelola penggabungan dan masa pakai HttpClientMessageHandlerinstance yang mendasarinya . Manajemen otomatis menghindari masalah DNS (Domain Name System) umum yang terjadi saat mengelola HttpClientmasa pakai secara manual .
  • Menambahkan pengalaman logging yang dapat dikonfigurasi (melalui ILogger) untuk semua permintaan yang dikirim melalui klien yang dibuat oleh pabrik.

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1

Mendirikan:

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.

Contoh 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

Ogglas
sumber
1

Anda benar bahwa ini telah lama diterapkan di .NET Core.

Pada saat penulisan (September 2019), project.jsonfile NuGet 3.x + telah digantikan oleh PackageReference(sebagaimana dijelaskan di https://docs.microsoft.com/en-us/nuget/archive/project-json ).

Untuk mendapatkan akses ke *Asyncmetode HttpClientkelas, .csprojfile Anda harus dikonfigurasi dengan benar.

Buka .csprojfile Anda di editor teks biasa, dan pastikan baris pertama adalah
<Project Sdk="Microsoft.NET.Sdk.Web">
(seperti yang ditunjukkan di https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj#the -csproj-format ).

Untuk mendapatkan akses ke *Asyncmetode HttpClientkelas, Anda juga harus memiliki referensi paket yang benar di .csprojfile Anda , seperti:

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

(Lihat https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference . Selain itu: Kami merekomendasikan aplikasi yang menargetkan ASP.NET Core 2.1 dan nanti gunakan metapackage Microsoft.AspNetCore.App , https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage )

Metode seperti PostAsJsonAsync, ReadAsAsync, PutAsJsonAsyncdan DeleteAsyncsekarang harus bekerja di luar kotak. (Tidak perlu menggunakan direktif.)

Pembaruan: Tag PackageReference tidak lagi diperlukan di .NET Core 3.0.

Henke
sumber
Saya tidak bisa mengatur PostAsJsonAsync untuk bekerja dengan .NET Core 3.1. Terima kasih
Chris Kolenko