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.

Kennzeichen
quelle

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);
pomber
quelle
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"));
carlosfigueira
quelle
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

user3285954
quelle
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
Suchen Sie dies oder etwas anderes? nuget.org/packages/Microsoft.AspNet.WebApi.Client
user3285954
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())
Matthew Steven Monkan
quelle
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;
Anthls
quelle
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

Stefano Ronchese
quelle