Benutzerdefinierter Header für HttpClient-Anforderung

140

Wie füge ich einer HttpClientAnfrage einen benutzerdefinierten Header hinzu ? Ich benutze die PostAsJsonAsyncMethode, um den JSON zu posten. Der benutzerdefinierte Header, den ich hinzufügen müsste, ist

"X-Version: 1"

Folgendes habe ich bisher getan:

using (var client = new HttpClient()) {
    client.BaseAddress = new Uri("https://api.clickatell.com/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "xxxxxxxxxxxxxxxxxxxx");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    var response = client.PostAsJsonAsync("rest/message", svm).Result;
}
Libin Joseph
quelle
3
Mögliches Duplikat des Hinzufügens von HTTP-Headern zu HTTPClient
Liam
@ Liam: Meine Frage war, wie man benutzerdefinierte Header hinzufügt. Wo als die andere Frage war, wie man Header hinzufügt
Libin Joseph
2
Ich denke, es wurde festgestellt, dass wir HttpClient nicht entsorgen sollten. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
Don Rolling

Antworten:

57
var request = new HttpRequestMessage {
    RequestUri = new Uri("[your request url string]"),
    Method = HttpMethod.Post,
    Headers = {
        { "X-Version", "1" } // HERE IS HOW TO ADD HEADERS,
        { HttpRequestHeader.Authorization.ToString(), "[your authorization token]" },
        { HttpRequestHeader.ContentType.ToString(), "multipart/mixed" },//use this content type if you want to send more than one content type
    },
    Content = new MultipartContent { // Just example of request sending multipart request
        new ObjectContent<[YOUR JSON OBJECT TYPE]>(
            new [YOUR JSON OBJECT TYPE INSTANCE](...){...}, 
            new JsonMediaTypeFormatter(), 
            "application/json"), // this will add 'Content-Type' header for the first part of request
        new ByteArrayContent([BINARY DATA]) {
            Headers = { // this will add headers for the second part of request
                { "Content-Type", "application/Executable" },
                { "Content-Disposition", "form-data; filename=\"test.pdf\"" },
            },
        },
    },
};
Anubis
quelle
38
Die Antwort ist äußerst verwirrend. Warum bringen Sie Code für Dokumente, blank.pdf usw. ein? Instanziieren von Bytearray-Klassen, um benutzerdefinierte Header innerhalb des Inhaltsparameters zu übergeben?
Heug
2
@heug Nun. Wenn Sie nach einem Header suchen, können Sie ihn sehen. Der Inhalt ist hier vorhanden, um das Bild zu vervollständigen, da Sie Ihrer Anfrage höchstwahrscheinlich Inhalt hinzufügen möchten. Und um nicht langweilig zu sein, ist der Inhalt kompliziert und enthält sowohl JSON- als auch Binärdaten.
Anubis
2
Es scheint einfach einfacher zu sein, dies so zu tun: Erstellen Sie StringContent mit Ihrem Content-JSON, erstellen Sie eine HTTP-Nachricht mit Ihrer Methode und Ihrem URI und fügen Sie dann Header wie message.Headers.Add ("x": "y") hinzu .... Übergeben Sie diese dann an eine Antwortvariable wie "var response = warte auf httpClient.SendAsync (message);"
Heug
@heug Ich werde mich für die Furute daran erinnern. Vielen Dank!
Anubis
3
Welche Zeile in der oben akzeptierten Antwort implementiert tatsächlich den vom OP angeforderten Header X-Version? Warum wird dies als akzeptierte Antwort angesehen?
Ron
215

Ich habe die Antwort auf meine Frage gefunden.

client.DefaultRequestHeaders.Add("X-Version","1");

Das sollte Ihrer Anfrage einen benutzerdefinierten Header hinzufügen

Libin Joseph
quelle
49
Nein, tut es nicht. Diese Antwort sollte mit Vorsicht betrachtet werden, da die Standardanforderungsheader mit jeder Anforderung gesendet werden. Sie sollten Ihre Anfrage wie von @Anubis vorgeschlagen erstellen. DefaultsRequestHeaders sollte beim Erstellen des HttpClient ausgefüllt werden.
Ruhrpottpatriot
6
Dies funktioniert nur, weil Sie für jede Anforderung einen neuen HttpClient instanziieren. Dies ist nicht die Art und Weise, wie diese Klasse verwendet werden sollte: Es sollte ein statisches Feld sein, das für alle Anforderungen wiederverwendet wird, zumindest für diejenigen an denselben Endpunkt. Siehe Dokumentation und unzählige Blog-Beiträge. Wie @Ruhrpottpatriot hervorhebt, wirkt sich das Ändern der Standardheader dann natürlich auf alle Anforderungen aus.
Kamilk
@Ruhrpottpatriot Was ist falsch daran, den Header für jede Anfrage zu senden?
David Klempfner
1
@ajbeaven Nein, das steht nicht. Das Beispiel oben auf der Seite zeigt die Hauptmethode der App. Obwohl der HttpClient entsorgt wird, wird dieselbe Instanz während der gesamten Lebensdauer der Anwendung verwendet, und dies ist in Bezug auf die Angaben in der Dokumentation korrekt etwas weiter unten: 'HttpClient soll einmal instanziiert und während der gesamten Lebensdauer einer Anwendung wiederverwendet werden' . Nach diesem Absatz wird ein Beispiel empfohlen, in dem empfohlen wird, einem statischen Feld einen HttpClient zuzuweisen.
Kamilk
1
@kamilk, du hast absolut recht - dieses Beispiel hat mich falsch gemacht. Danke, dass du mich in Ordnung gebracht hast :)
ajbeaven
78

Hier ist eine Antwort, die auf der Antwort von Anubis basiert (was ein besserer Ansatz ist, da die Header nicht für jede Anfrage geändert werden), aber dem Code in der ursprünglichen Frage besser entspricht:

using Newtonsoft.Json;
...

    var client = new HttpClient();
    var httpRequestMessage = new HttpRequestMessage
        {
            Method = HttpMethod.Post,
            RequestUri = new Uri("https://api.clickatell.com/rest/message"),
            Headers = { 
                { HttpRequestHeader.Authorization.ToString(), "Bearer xxxxxxxxxxxxxxxxxxxx" },
                { HttpRequestHeader.Accept.ToString(), "application/json" },
                { "X-Version", "1" }
            },
            Content = new StringContent(JsonConvert.SerializeObject(svm))
        };

    var response = client.SendAsync(httpRequestMessage).Result;
Chris Peacock
quelle
@ RossPresser definitiv nicht. Der Inhaltstyp ist ein Inhaltsheader.
Panagiotis Kanavos
1
Einverstanden ist dies die Antwort. Es wird gezeigt, wie der von OP angeforderte Header hinzugefügt wird. Beantwortete auch meine Frage.
Ron
1
Zu Ihrer Information, ich denke HttpRequestHeader.Accesssollte sein HttpRequestHeader.Accept.
Mass Dot Net
was ist svm übrigens?
Aswzen
@aswzen Es ist aus der Frage des OP - etwas Modell, das ich vermuten würde. Das zu serialisierende Objekt.
Chris Peacock
2

Es gibt eine HeadersEigenschaft in der HttpRequestMessageKlasse. Dort können Sie benutzerdefinierte Header hinzufügen, die bei jeder HTTP-Anforderung gesendet werden. Das DefaultRequestHeadersin der HttpClientKlasse legt andererseits Header fest, die mit jeder Anforderung gesendet werden sollen, die mit diesem Clientobjekt gesendet wird, daher der Name Standardanforderungsheader .

Ich hoffe, dies macht die Dinge klarer, zumindest für jemanden, der diese Antwort in Zukunft sieht.

Bob der Baumeister
quelle
Nein, macht es nicht klarer. In beiden Fällen sagen Sie, dass Sie bei jeder Anfrage Header senden. Was ist also der Unterschied?
Joedotnot
3
Headersist eine Eigenschaft eines einzelnen HttpRequestMessageObjekts. So können Sie unterschiedliche Nachrichten mit unterschiedlichen Headern erstellen. DefaultRequestHeadersist eine Eigenschaft des HttpClientObjekts; Wenn mehrere Nachrichten über eine bestimmte Nachricht gesendet werden HttpClient, werden alle diese Nachrichten gleich DefaultRequestHeaderszu den einzelnen Headern der Nachricht hinzugefügt.
Ross Presser