POSTEN von JsonObject mit HttpClient von der Web-API


288

Ich versuche, eine JsonObjectVerwendung HttpClientvon der Web-API zu POSTEN. Ich bin mir nicht ganz sicher, wie ich das anstellen soll, und kann nicht viel an Beispielcode finden.

Folgendes habe ich bisher:

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

Ich denke, ich muss meine JsonObjectals StreamContentbesetzen, aber ich werde auf diesen Schritt aufgehängt.

Antworten:


440

Mit der neuen Version von HttpClientund ohne das WebApiPaket wäre es:

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

Oder wenn du es willst async:

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

3
Dieser überladene StringContent-Konstruktor hat den Trick für mich getan.
Kapitän Kenpachi

23
Überlegen Sie zweimal, bevor Sie Result für eine Async-Methode aufrufen, obwohl blog.stephencleary.com/2012/07/dont-block-on-async-code.html
Ruchira

2
Für alle, die versucht waren, dies so zu werfen, usingwie ich es war: aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
maxshuty

Ich habe usingdie StringContentKreation allerdings umgangen.
bcr

Mit dieser Antwort erhielt ich immer wieder die Antwort "400 Bad Request" von einer API, an die ich meine JSON-Anfrage gesendet habe (Visual Studio 2017, .NET 4.6.2). Außerdem musste var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json")ich einstellen content.Headers.ContentType = new MediaTypeHeaderValue("application/json");. Siehe Antwort unten für weitere Details.
Anthls

161

Am einfachsten ist es, a StringContentmit der JSON-Darstellung Ihres JSON-Objekts zu verwenden.

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

14
Beachten Sie den Inhaltstyp. Ich habe es weggelassen und mich viel länger debuggen lassen, als ich möchte.
Zapnologica

Sollten Sie die StringContent-Instanz nicht entsorgen?
Phil Haselden

63

Abhängig von Ihrer .NET-Version können Sie auch die HttpClientExtensions.PostAsJsonAsyncMethode verwenden.

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


4
Jetzt gefunden in Microsoft.AspNet.Client.WebApi nuget
jle

2
Ich habe es gerade von Microsoft.AspNet.WebApi.Client
Adriaan Davel

Dies löste mein Problem. Ich habe (lange) herumgespielt, während ich eine C # -Klasse übergeben habe, die einige Eigenschaften enthielt, die Listen mit client.PostAsync, client.SendAsync waren. Ich habe sehr gemischte Ergebnisse erhalten. Wenn das Array leer wäre, würde meine API-Lösung es abholen, aber wenn das Array ein Element hätte, könnte die Controller-Methode den JSON nicht modellieren. Vielen Dank dafür. Mir scheint, dass PostAsJsonAsync ein komplexes C # -Objekt zuverlässiger in JSON konvertiert.
Franklin Tarter

Gibt es dafür ein Nuget-Paket? Ich hasse es, wenn ich das Projekt auf eine neue Maschine übertrage, und diese Referenz fehlt immer.
Zapnologica


51

Bei Verwendung von 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");
}

Beispiel:

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

Dies ist nicht asp.net Kern spezifisch, es ist tatsächlich generisch bis auf 4.5.6
Danatcofo

JsonConvert.SerializeObjectProbleme mit DateTimes ISO 8601 Art: Lokal oder UTC ... hackered.co.uk/articles/…
Kiquenet

21

Ich habe nicht genug Ruf, um einen Kommentar zur Antwort von pomber hinzuzufügen, also poste ich eine andere Antwort. Mit dem Ansatz von pomber erhielt ich immer wieder die Antwort "400 Bad Request" von einer API, an die ich meine JSON-Anfrage gesendet habe (Visual Studio 2017, .NET 4.6.2). Schließlich wurde das Problem darauf zurückgeführt, dass der von StringContent () erzeugte Header "Content-Type" falsch war (siehe https://github.com/dotnet/corefx/issues/7864 ).

tl; dr

Verwenden Sie die Antwort von pomber mit einer zusätzlichen Zeile, um den Header für die Anforderung korrekt festzulegen:

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

Danke, Anthls. var content = new StringContent (jsonObject.ToString (), Encoding.UTF8, "application / json") war nicht genug. Es benötigt content.Headers.ContentType = new MediaTypeHeaderValue ("application / json"); Danke, dass du meine geistige Gesundheit gerettet hast.
Gail Foad

1
Das hat super geklappt. Gibt es einen Grund, warum "application / json" zweimal festgelegt werden muss, einmal im Konstruktor und einmal über die Eigenschaft? Ist es ein Fehler?
Festus Martingale

@FestusMartingale: gute Frage! Nach meiner Lektüre des Github-Problems (in der Antwort verlinkt) ist die Übergabe "application/json"im StringContentKonstruktor wahrscheinlich nicht erforderlich, da sie explizit für die resultierende content.Headers.ContentTypeEigenschaft festgelegt wird. Ich habe dies jedoch nicht im Code getestet.
Anthls

Es sieht so aus, als ob der Server die Zeichenfolge für den vollständigen Inhaltstyp nicht unterstützt. Wenn Sie den Konstruktor verwenden, ohne den ContentType zu überschreiben, wird der Wert auf festgelegt application/json; charset=utf-8.
Bertm13

2

der Code darüber in 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)

Ich hoffe das hilft

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.