POSTing JsonObject Dengan HttpClient Dari Web API

288

Saya mencoba POST suatu JsonObjectpenggunaan HttpClientdari Web API. Saya tidak begitu yakin bagaimana cara melakukannya dan tidak dapat menemukan banyak cara kode sampel.

Inilah yang saya miliki sejauh ini:

var myObject = (dynamic)new JsonObject();
myObject.Data = "some data";
myObject.Data2 = "some more data";

HttpClient httpClient = new HttpClient("myurl");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

HttpResponseMessage response = httpClient.Post("", ???);

Saya pikir saya perlu melemparkan saya JsonObjectsebagai StreamContenttapi saya terpaku pada langkah itu.

Menandai
sumber

Jawaban:

440

Dengan versi baru HttpClientdan tanpa WebApipaket itu akan menjadi:

var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
var result = client.PostAsync(url, content).Result;

Atau jika Anda menginginkannya async:

var result = await client.PostAsync(url, content);
pomber
sumber
3
Konstruktor StringContent yang kelebihan beban melakukan trik untuk saya.
Kapten Kenpachi
23
Berpikir dua kali sebelum memanggil Hasil pada metode Async melalui blog.stephencleary.com/2012/07/dont-block-on-async-code.html
Ruchira
2
Bagi siapa pun yang tergoda untuk melempar ini usingseperti saya adalah: aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
maxshuty
Saya menempatkan usingsekitar StringContentpenciptaan sekalipun.
bcr
Dengan menggunakan jawaban ini, saya terus menerima respons "400 Permintaan Buruk" dari API yang saya kirimi permintaan JSON saya (Visual Studio 2017, .NET 4.6.2). Selain var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json")saya harus mengatur content.Headers.ContentType = new MediaTypeHeaderValue("application/json");. Lihat jawaban di bawah untuk detail lebih lanjut.
anthls
161

Cara termudah adalah dengan menggunakan StringContent, dengan representasi JSON dari objek JSON Anda.

httpClient.Post(
    "",
    new StringContent(
        myObject.ToString(),
        Encoding.UTF8,
        "application/json"));
carlosfigueira
sumber
14
Perhatikan jenis kontennya. Saya meninggalkannya dan meminta saya melakukan debug lebih lama dari yang saya inginkan.
Zapnologica
Bukankah Anda seharusnya membuang instance StringContent?
Phil Haselden
63

Bergantung pada versi .NET Anda, Anda juga dapat menggunakan HttpClientExtensions.PostAsJsonAsyncmetode.

https://msdn.microsoft.com/en-us/library/system.net.http.httpclientextensions.postasjsonasync.aspx

pengguna3285954
sumber
4
Sekarang ditemukan di Microsoft.AspNet.Client.WebApi nuget
jle
2
Saya baru saja menginstalnya dari Microsoft.AspNet.WebApi.Client
Adriaan Davel
Ini menyelesaikan masalah saya. Saya bermain-main untuk (lama) saat melewati kelas C # yang berisi beberapa properti yang Daftar menggunakan client.PostAsync, client.SendAsync .. Saya mendapatkan hasil yang sangat beragam. Jika array kosong, solusi API saya akan mengambilnya, tetapi jika array memiliki item, metode pengontrol tidak dapat memodelkan mengikat JSON. Terima kasih untuk ini .. Menurut saya PostAsJsonAsync lebih dapat dipercaya mengubah objek C # yang kompleks menjadi JSON.
Franklin Tarter
Apakah ada paket nuget untuk ini? Saya benci ketika saya mentransfer proyek ke mesin baru, dan referensi ini selalu hilang.
Zapnologica
Mencari ini atau yang lainnya? nuget.org/packages/Microsoft.AspNet.WebApi.Client
user3285954
51

Jika menggunakan Newtonsoft.Json:

using Newtonsoft.Json;
using System.Net.Http;
using System.Text;

public static class Extensions
{
    public static StringContent AsJson(this object o)
        => new StringContent(JsonConvert.SerializeObject(o), Encoding.UTF8, "application/json");
}

Contoh:

var httpClient = new HttpClient();
var url = "https://www.duolingo.com/2016-04-13/login?fields=";
var data = new { identifier = "username", password = "password" };
var result = await httpClient.PostAsync(url, data.AsJson())
Matthew Steven Monkan
sumber
ini bukan inti spesifik asp.net, ini sebenarnya generik hingga 4.5.6
danatcofo
JsonConvert.SerializeObjectmasalah menggunakan DateTimes ISO 8601 Jenis: Lokal atau UTC ... hackered.co.uk/articles/…
Kiquenet
21

Saya tidak memiliki reputasi yang cukup untuk menambahkan komentar pada jawaban dari pomber jadi saya memposting jawaban lain. Dengan menggunakan pendekatan pomber, saya terus menerima respons "400 Permintaan Buruk" dari API yang saya kirimi permintaan JSON saya ke (Visual Studio 2017, .NET 4.6.2). Akhirnya masalah ditelusuri ke header "Tipe-Konten" yang dihasilkan oleh StringContent () salah (lihat https://github.com/dotnet/corefx/issues/7864 ).

tl; dr

Gunakan jawaban pomber dengan garis tambahan untuk mengatur header dengan benar pada permintaan:

var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result = client.PostAsync(url, content).Result;
anthls
sumber
Terima kasih, anthls. konten var = StringContent baru (jsonObject.ToString (), Encoding.UTF8, "application / json") tidak cukup. Perlu content.Headers.ContentType = new MediaTypeHeaderValue ("application / json"); Terima kasih telah menyelamatkan kewarasan saya.
Gail Foad
1
Ini bekerja dengan baik. Adakah alasan mengapa "application / json" perlu disetel dua kali, satu di konstruktor dan sekali melalui properti? Apakah ini bug?
Festus Martingale
@FestusMartingale: pertanyaan bagus! Dari pembacaan saya tentang masalah github (terkait dalam jawaban), lewat "application/json"dalam StringContentkonstruktor mungkin tidak diperlukan karena sedang diatur secara eksplisit pada content.Headers.ContentTypeproperti yang dihasilkan . Namun, saya belum menguji ini dalam kode.
anthls
Sepertinya server tidak mendukung string tipe konten lengkap. Saat Anda menggunakan konstruktor tanpa mengabaikan ContentType, itu menetapkan nilai sebagai application/json; charset=utf-8.
Bertm13
2

kode di atasnya di vbnet:

dim FeToSend as new (object--> define class)

Dim client As New HttpClient
Dim content = New StringContent(FeToSend.ToString(), Encoding.UTF8,"application/json")
content.Headers.ContentType = New MediaTypeHeaderValue( "application/json" )
Dim risp = client.PostAsync(Chiamata, content).Result

msgbox(risp.tostring)

Semoga bantuan ini

Stefano Ronchese
sumber