Niestandardowy nagłówek żądania HttpClient

140

Jak dodać niestandardowy nagłówek do HttpClientżądania? Używam PostAsJsonAsyncmetody, aby opublikować JSON. Niestandardowy nagłówek, który musiałbym dodać, to

"X-Version: 1"

Oto, co zrobiłem do tej pory:

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
źródło
3
Możliwy duplikat dodawania nagłówków HTTP do HttpClient
Liam,
@Liam: Moje pytanie dotyczyło dodawania niestandardowych nagłówków. Gdzie drugim pytaniem było, jak dodać nagłówki
Libin Joseph
2
Myślę, że stwierdzono, że nie powinniśmy pozbywać się HttpClient. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
Don Rolling

Odpowiedzi:

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
źródło
38
odpowiedź jest bardzo zagmatwana ... dlaczego przynosisz kod dla dokumentów, pusty.pdf itp.? tworzenie wystąpień klas bytearray do przekazywania niestandardowych nagłówków w parametrze Content?
heug
2
@heug Well. Jeśli szukasz nagłówka, możesz go zobaczyć. Treść jest obecna tutaj, aby uzupełnić obraz, ponieważ najprawdopodobniej chcesz dodać treść do swojego żądania. Aby nie być uciążliwym, zawartość jest skomplikowana i zawiera zarówno dane JSON, jak i dane binarne.
Anubis
2
wydaje się po prostu prostsze, aby zrobić to w ten sposób: utwórz StringContent za pomocą JSON zawartości, utwórz wiadomość HTTP ze swoją metodą i identyfikatorem URI, a następnie dodaj nagłówki, takie jak message.Headers.Add ("x": "y") .... następnie przekaż je do odpowiedzi var, na przykład „var response = await httpClient.SendAsync (message);”
heug
@heug Zapamiętam to dla furute. Dzięki!
Anubis
3
Która linia w powyższej zaakceptowanej odpowiedzi faktycznie implementuje nagłówek żądany przez OP, X-Version? Dlaczego jest to uważane za zaakceptowaną odpowiedź?
Ron
215

Znalazłem odpowiedź na swoje pytanie.

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

To powinno dodać niestandardowy nagłówek do twojego żądania

Libin Joseph
źródło
50
Nie. Tę odpowiedź należy traktować ostrożnie, ponieważ domyślne nagłówki żądań są wysyłane z każdym żądaniem. Powinieneś zbudować swoją prośbę, jak sugerował @Anubis. DefaultsRequestHeaders należy wypełnić podczas tworzenia HttpClient.
Ruhrpottpatriot
6
Działa to tylko dlatego, że tworzysz wystąpienie nowego HttpClient dla każdego żądania. Nie w ten sposób należy używać tej klasy: powinno to być pole statyczne, używane ponownie dla wszystkich żądań, przynajmniej tych do tego samego punktu końcowego. Zobacz dokumentację i niezliczone posty na blogu. Następnie, oczywiście, jak wskazuje @Ruhrpottpatriot, zmiana domyślnych nagłówków wpłynie na wszystkie żądania.
kamilk
@Ruhrpottpatriot Co jest złego w wysyłaniu nagłówka dla każdego żądania?
David Klempfner
1
@ajbeaven Nie, nie o tym mówi. Przykład u góry strony przedstawia metodę Main aplikacji, więc nawet jeśli HttpClient zostanie usunięty, to samo wystąpienie jest używane przez cały okres istnienia aplikacji i jest to poprawne w odniesieniu do tego, co mówi trochę dokumentacja Nieco dalej: „HttpClient ma być utworzony raz i ponownie użyty przez cały okres istnienia aplikacji” . Po tym akapicie znajduje się przykład zalecający przypisanie HttpClient do pola statycznego.
kamilk
1
@kamilk, masz całkowitą rację - ten przykład mnie źle zrozumiał. Dzięki za
poprawienie
79

Oto odpowiedź oparta na odpowiedzi Anubisa (co jest lepszym podejściem, ponieważ nie modyfikuje nagłówków dla każdego żądania), ale która jest bardziej równoważna z kodem w oryginalnym pytaniu:

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
źródło
@RossPresser zdecydowanie nie. Content-Type to nagłówek treści.
Panagiotis Kanavos
1
Zgoda, to odpowiedź. Pokazuje, jak dodać nagłówek, którego zażądał OP. Odpowiedział również na moje pytanie.
Ron
1
FYI, myślę, że HttpRequestHeader.Accesspowinno być HttpRequestHeader.Accept.
Mass Dot Net
co to jest svm?
aswzen
@aswzen To z pytania OP - coś modelowego chyba. Serializowany obiekt.
Chris Peacock,
2

W klasie jest Headerswłaściwość HttpRequestMessage. Możesz tam dodać niestandardowe nagłówki, które będą wysyłane z każdym żądaniem HTTP. Z drugiej strony klasa DefaultRequestHeadersw HttpClientklasie ustawia nagłówki, które mają być wysyłane z każdym żądaniem wysyłanym przy użyciu tego obiektu klienta, stąd nazwa Default Request Headers.

Mam nadzieję, że to wszystko wyjaśni, przynajmniej dla kogoś, kto zobaczy tę odpowiedź w przyszłości.

Bob Budowniczy
źródło
1
Nie, nie wyjaśnia tego bardziej. W obu przypadkach mówisz, że wysyłasz nagłówki na każde żądanie - więc jaka jest różnica?
joedotnot
3
Headersjest własnością pojedynczego HttpRequestMessageprzedmiotu. W ten sposób możesz tworzyć różne wiadomości z różnymi nagłówkami. DefaultRequestHeadersjest własnością HttpClientprzedmiotu; jeśli przez daną wysyłanych jest wiele wiadomości HttpClient, wszystkie takie wiadomości będą miały to samo DefaultRequestHeadersdodane do poszczególnych nagłówków wiadomości.
Ross Presser