โพสต์ JsonObject ด้วย HttpClient จาก Web API


289

ฉันกำลังพยายามโพสต์การJsonObjectใช้HttpClientจาก Web API ฉันค่อนข้างไม่แน่ใจว่าจะทำอย่างไรและไม่สามารถหาโค้ดได้มากนัก

นี่คือสิ่งที่ฉันมี:

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("", ???);

ฉันคิดว่าฉันต้องทำให้ตัวเองJsonObjectเป็นStreamContentแต่ฉันก็ถูกวางสายในขั้นตอนนั้น

คำตอบ:


441

ด้วยเวอร์ชันใหม่ของHttpClientและไม่มีWebApiแพ็คเกจมันจะเป็น:

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

หรือถ้าคุณต้องการasync:

var result = await client.PostAsync(url, content);

3
ตัวสร้าง StringContent ที่มากเกินไปทำเคล็ดลับสำหรับฉัน
กัปตัน Kenpachi

23
คิดว่าสองครั้งก่อนที่จะเรียกผลโดยวิธี Async แม้ว่าblog.stephencleary.com/2012/07/dont-block-on-async-code.html
Ruchira

2
สำหรับใครก็ตามที่อยากจะโยนสิ่งนี้ในแบบที่usingฉันเป็น: aspnetmonsters.com 2016/08/2016-08-27
httpclientwrong

ฉันใส่usingรอบการStringContentสร้างแม้ว่า
bcr

ใช้คำตอบนี้ฉันได้รับการตอบสนอง "400 คำขอไม่ถูกต้อง" จาก API ฉันโพสต์คำขอ JSON ของฉันไปที่ (Visual Studio 2017, .NET 4.6.2) นอกเหนือจากการที่ผมต้องชุดvar content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json") content.Headers.ContentType = new MediaTypeHeaderValue("application/json");ดูคำตอบด้านล่างสำหรับรายละเอียดเพิ่มเติม
anthls

161

วิธีที่ง่ายที่สุดคือการใช้ a โดยใช้StringContentการแสดง JSON ของวัตถุ JSON ของคุณ

httpClient.Post(
    "",
    new StringContent(
        myObject.ToString(),
        Encoding.UTF8,
        "application/json"));

14
จดบันทึกในประเภทเนื้อหา ฉันปล่อยมันไว้และให้ฉันดีบั๊กนานกว่าที่ฉันต้องการ
Zapnologica

คุณไม่ควรกำจัดตัวอย่างของ StringContent
Phil Haselden

63

ทั้งนี้ขึ้นอยู่กับรุ่น. NET ของคุณคุณสามารถใช้HttpClientExtensions.PostAsJsonAsyncวิธีการ

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


4
พบได้ใน Microsoft.AspNet.Client.WebApi nuget
jle

2
ฉันเพิ่งติดตั้งจาก Microsoft.AspNet.WebApi.Client
Adriaan Davel

นี่เป็นการแก้ไขปัญหาของฉัน ฉันล้อเล่นรอบ (ยาว) ในขณะที่ผ่านคลาส C # ที่มีคุณสมบัติบางอย่างที่เป็นรายการที่ใช้ client.PostAsync, client.SendAsync .. ฉันได้รับผลลัพธ์ที่หลากหลายมาก หากอาเรย์นั้นว่างเปล่าโซลูชัน API ของฉันจะมารับมัน แต่ถ้าอาเรย์นั้นมีไอเท็มเมธอดคอนโทรลเลอร์ไม่สามารถสร้างโมเดล JSON ได้ ขอบคุณสำหรับสิ่งนี้ .. ดูเหมือนว่า PostAsJsonAsync น่าเชื่อถือมากขึ้นในการแปลงวัตถุ C # ที่ซับซ้อนเป็น JSON
Franklin Tarter

มีแพ็กเกจ nuget สำหรับสิ่งนี้หรือไม่? ฉันเกลียดเมื่อฉันโอนโครงการไปยังเครื่องใหม่และการอ้างอิงนี้หายไปเสมอ
Zapnologica

กำลังมองหาสิ่งนี้หรืออย่างอื่น? nuget.org/packages/Microsoft.AspNet.WebApi.Client
user3285954

51

หากใช้ 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");
}

ตัวอย่าง:

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())

นี้ไม่ได้เป็นแกนหลักเฉพาะของ asp.net แต่จริงๆแล้วมันลดลงเหลือ 4.5.6
danatcofo

JsonConvert.SerializeObjectปัญหาในการใช้DateTimes ISO 8601ชนิด: ท้องถิ่นหรือ UTC ... hackered.co.uk/articles/
Kiquenet

21

ฉันไม่มีชื่อเสียงพอที่จะเพิ่มความคิดเห็นเกี่ยวกับคำตอบจาก pomber ดังนั้นฉันจึงโพสต์คำตอบอื่น ด้วยวิธีการของ pomber ฉันได้รับการตอบสนอง "400 คำขอไม่ถูกต้อง" จาก API ฉันโพสต์คำขอ JSON ของฉันไปที่ (Visual Studio 2017, .NET 4.6.2) ในที่สุดปัญหาถูกสืบค้นกลับไปที่ส่วนหัว "Content-Type" ที่ผลิตโดย StringContent () ไม่ถูกต้อง (ดูhttps://github.com/dotnet/corefx/issues/7864 )

TL; DR

คำตอบที่ใช้ pomber กับสายพิเศษที่จะตั้งอย่างถูกต้องส่วนหัวตามคำขอนี้:

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 var content = ใหม่ StringContent (jsonObject.ToString (), Encoding.UTF8, "application / json") ไม่เพียงพอ ต้องการ content.Headers.ContentType = new MediaTypeHeaderValue ("application / json"); ขอขอบคุณที่ช่วยรักษาสติของฉัน
Gail Foad

1
มันใช้งานได้ดีมาก เหตุผลใดที่ "แอปพลิเคชัน / json" จะต้องตั้งค่าสองครั้งหนึ่งในตัวสร้างและอีกครั้งผ่านคุณสมบัติ? มันเป็นข้อบกพร่องหรือไม่?
Festus Martingale

@FestusMartingale: เป็นคำถามที่ดี! จากการอ่านปัญหา github ของฉัน (เชื่อมโยงในคำตอบ) การส่งผ่านของ"application/json"ในคอนStringContentสตรัคเตอร์อาจไม่จำเป็นเนื่องจากมันถูกกำหนดไว้อย่างชัดเจนในcontent.Headers.ContentTypeคุณสมบัติที่เป็นผลลัพธ์ อย่างไรก็ตามฉันยังไม่ได้ทดสอบในรหัส
anthls

ดูเหมือนว่าเซิร์ฟเวอร์ไม่รองรับสตริงประเภทเนื้อหาทั้งหมด เมื่อคุณใช้ตัวสร้างโดยไม่ต้องเอาชนะ ContentType application/json; charset=utf-8ก็ตั้งค่าเป็น
Bertm13

2

รหัสมากกว่านั้นใน 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)

หวังว่าความช่วยเหลือนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.