1145 Stimmen

Wie legt man den Content-Type-Header für eine HttpClient-Anfrage fest?

Ich versuche, die Content-Type Kopfzeile eines HttpClient Objekt, wie es von einer API, die ich aufrufe, benötigt wird.

Ich habe versucht, die Einstellung Content-Type wie unten:

using (var httpClient = new HttpClient())
{
    httpClient.BaseAddress = new Uri("http://example.com/");
    httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    httpClient.DefaultRequestHeaders.Add("Content-Type", "application/json");
    // ...
}

Sie ermöglicht es mir, die Accept Kopfzeile, aber wenn ich versuche, die Content-Type löst er die folgende Ausnahme aus:

Falsch verwendeter Kopfzeilenname. M HttpRequestMessage Antwort-Header mit HttpResponseMessage und Inhaltskopfzeilen mit HttpContent Objekte.

Wie kann ich die Content-Type Kopfzeile in einer HttpClient Anfrage?

35voto

Hassan Faghihi Punkte 1664

Für diejenigen, die Probleme haben mit charset

Ich hatte einen sehr speziellen Fall, in dem der Dienstanbieter den Zeichensatz nicht akzeptierte und sich weigerte, die Unterstruktur zu ändern, um ihn zuzulassen... Leider HttpClient wurde die Kopfzeile automatisch durch StringContent festgelegt, und egal, ob Sie null oder Encoding.UTF8 übergeben, es wird immer den Zeichensatz festgelegt...

Heute war ich auf der Kante zu ändern, die sub-System; Umzug von HttpClient zu etwas anderes, dass etwas in den Sinn kam ..., warum nicht verwenden Sie Reflexion zu leeren, die "Zeichensatz"? ... Und bevor ich es sogar versuchen, dachte ich an einen Weg, "vielleicht kann ich es nach der Initialisierung ändern", und das funktionierte.

Hier sehen Sie, wie Sie den genauen "application/json"-Header ohne "; charset=utf-8" setzen können.

var jsonRequest = JsonSerializeObject(req, options); // Custom function that parse object to string
var stringContent = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
stringContent.Headers.ContentType.CharSet = null;
return stringContent;

Anmerkung: Die null Wert im Folgenden wird nicht funktionieren, und fügen Sie "; charset=utf-8" hinzu

return new StringContent(jsonRequest, null, "application/json");

EDITAR

@DesertFoxAZ schlägt vor, dass auch der folgende Code verwendet werden kann und gut funktioniert. (habe es nicht selbst getestet, wenn es funktioniert, bewerten Sie es und schreiben Sie es in die Kommentare)

stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

27voto

Jay Punkte 8769

Einige zusätzliche Informationen über .NET Core (nach dem Lesen von erdomke's Beitrag über das Setzen eines privaten Feldes, um den Content-Type bei einer Anfrage ohne Inhalt zu liefern)...

Nach dem Debuggen meines Codes, kann ich nicht sehen, das private Feld über Reflexion zu setzen - so dachte ich, ich würde versuchen, das Problem neu zu erstellen.

Ich habe den folgenden Code mit .Net 4.6 ausprobiert:

HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, @"myUrl");
httpRequest.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");

HttpClient client = new HttpClient();
Task<HttpResponseMessage> response =  client.SendAsync(httpRequest);  //I know I should have used async/await here!
var result = response.Result;

Und, wie erwartet, erhalte ich eine aggregierte Ausnahme mit dem Inhalt "Cannot send a content-body with this verb-type."

Wenn ich jedoch dasselbe mit .NET Core (1.1) mache - Ich bekomme keine Ausnahme. Meine Anfrage wurde von meiner Serveranwendung zufriedenstellend beantwortet, und der Inhaltstyp wurde übernommen.

Ich war angenehm überrascht, und ich hoffe, es hilft jemandem!

25voto

Roland Punkte 3869

Der Trick ist, dass man einfach alle möglichen Kopfzeilen einstellen kann, wie:

HttpRequestMessage request = new HttpRequestMessage();
request.Headers.Add("Accept-Language", "en"); //works OK

aber keine Kopfzeile. Zum Beispiel:

request.Headers.Add("Content-Type", "application/json");//wrong

löst die Laufzeitausnahme Misused header name . Es mag den Anschein haben, dass dies funktionieren wird:

request.Headers.Add(
   HttpRequestHeader.ContentType.ToString(), //useless
   "application/json"
);

aber das ergibt eine nutzlose Kopfzeile namens ContentType , ohne Bindestrich. Bei Kopfzeilennamen wird nicht zwischen Groß- und Kleinschreibung unterschieden, aber sehr stark auf Bindestriche geachtet.

Die Lösung ist die Angabe der Kodierung und des Typs des Bodys beim Hinzufügen des Bodys zum Inhaltsteil der HTTP-Anforderung:

string Body = "...";
request.Content =
   new StringContent(Body, Encoding.UTF8, "application/json");

Nur dann wird der entsprechende http-Header automatisch zur Anfrage hinzugefügt:

Content-Type: application/json; charset=utf-8

Es war schwierig, dies mit Fiddler auf einem Rechner ohne Proxyserver herauszufinden. Visual Studio hatte früher ein Netzwerk-Tool, mit dem man alle Header untersuchen konnte, aber nur in Version 2015, nicht in den neueren Versionen 2017 oder 2022. Wenn Sie den Debugger verwenden, um zu prüfen request.Headers finden Sie die Kopfzeile nicht automatisch hinzugefügt durch StringContent() .

23voto

Robert Levy Punkte 28351

コール AddWithoutValidation 代わりに Add (siehe dieser MSDN-Link ).

Alternativ vermute ich, dass die API, die Sie verwenden, dies nur für POST- oder PUT-Anfragen erfordert (nicht für gewöhnliche GET-Anfragen). In diesem Fall, wenn Sie aufrufen HttpClient.PostAsync und geben Sie eine HttpContent setzen Sie dies auf die Headers Eigenschaft dieser HttpContent Objekt.

8voto

Kumaran Punkte 76

Sie können dies verwenden, wird es Arbeit sein!

HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Get,"URL");
msg.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");

HttpResponseMessage response = await _httpClient.SendAsync(msg);
response.EnsureSuccessStatusCode();

string json = await response.Content.ReadAsStringAsync();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X