Пользовательский заголовок для запроса HttpClient

140

Как добавить пользовательский заголовок в HttpClientзапрос? Я использую PostAsJsonAsyncметод, чтобы опубликовать JSON. Пользовательский заголовок, который мне нужно добавить,

"X-Version: 1"

Это то, что я сделал до сих пор:

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;
}
Либин Иосиф
источник
3
Возможный дубликат добавления заголовков Http в HttpClient
Liam
@Liam: Мой вопрос был о том, как добавить пользовательские заголовки. Где в качестве другого вопроса было, как добавить заголовки
Libin Joseph
2
Я думаю, что было обнаружено, что мы не должны избавляться от HttpClient. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
Дон Роллинг

Ответы:

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\"" },
            },
        },
    },
};
Анубис
источник
38
ответ очень запутанный ... почему вы вводите код для документов, blank.pdf и т. д.? создание экземпляров классов bytearray для передачи пользовательских заголовков в параметре Content?
августа
2
@heug Хорошо. Если вы ищете заголовок, вы можете увидеть его. Контент присутствует здесь для того, чтобы завершить картину, потому что вы, скорее всего, хотите добавить контент к вашему запросу. И чтобы не быть утомительным, контент сложен и содержит как JSON, так и двоичные данные.
Анубис
2
просто кажется более простым сделать это следующим образом: создать StringContent с использованием содержимого JSON, создать сообщение HTTP с вашим методом и URI, а затем добавить заголовки, такие как message.Headers.Add ("x": "y") .... затем передайте их в ответную переменную типа "var response = await httpClient.SendAsync (message);"
августа
@heug Я запомню это для будущего. Спасибо!
Анубис
3
Какая строка в принятом выше ответе фактически реализует заголовок, запрошенный OP, X-Version? Почему это считается принятым ответом?
Рон
215

Я нашел ответ на свой вопрос.

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

Это должно добавить пользовательский заголовок к вашему запросу

Либин Иосиф
источник
50
Нет. Этот ответ следует рассматривать с осторожностью, поскольку заголовки запроса по умолчанию отправляются с каждым запросом. Вы должны создать свой запрос, как предложено @Anubis. DefaultsRequestHeaders должен быть заполнен при создании HttpClient.
Ruhrpottpatriot
6
Это работает только потому, что вы создаете новый HttpClient для каждого запроса. Это не тот способ, которым должен использоваться этот класс: это должно быть статическое поле, многократно используемое для всех запросов, по крайней мере, для одной и той же конечной точки. Смотрите документацию и бесчисленные посты в блоге там. Затем, как, конечно, @Ruhrpottpatriot указывает, изменение заголовков по умолчанию повлияет на все запросы.
Камилк
@Ruhrpottpatriot Что не так с отправкой заголовка для каждого запроса?
Дэвид Клемпфнер
1
@ajbeaven Нет, это не то, что говорится. В примере в верхней части страницы показан метод Main приложения, поэтому, несмотря на то, что HttpClient удаляется, один и тот же экземпляр используется на протяжении всего жизненного цикла приложения, и это правильно в отношении того, что в документации говорится немного немного ниже: «HttpClient предназначен для создания экземпляра один раз и повторного использования в течение всей жизни приложения» . После этого параграфа приведен пример, рекомендующий присвоить HttpClient статическому полю.
Камилк
1
@kamilk, ты совершенно прав - этот пример ошибся. Спасибо, что
поправили
79

Вот ответ, основанный на этом Anubis (который является лучшим подходом, поскольку он не изменяет заголовки для каждого запроса), но который более эквивалентен коду в исходном вопросе:

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;
Крис Пикок
источник
@RossPresser определенно нет. Content-Type - это заголовок контента.
Панагиотис Канавос
1
Согласен, это ответ. Он демонстрирует, как добавить заголовок, запрошенный OP. Ответил и на мой вопрос.
Рон
1
К вашему сведению, HttpRequestHeader.Accessдолжно быть HttpRequestHeader.Accept.
Mass Dot Net
что такое svm кстати?
aswzen
@aswzen Это вопрос ОП - что-то вроде модели. Объект сериализуется.
Крис Пикок
2

В классе есть Headersсвойство HttpRequestMessage. Там вы можете добавить свои заголовки, которые будут отправляться с каждым HTTP-запросом. Класс DefaultRequestHeadersin HttpClient, с другой стороны, устанавливает заголовки, которые будут отправляться при каждом запросе, отправляемом с использованием этого объекта клиента, отсюда и название Заголовки запросов по умолчанию .

Надеюсь, это прояснит ситуацию, по крайней мере, для того, кто увидит этот ответ в будущем.

Боб-строитель
источник
1
Нет, не делает это более понятным. В обоих случаях вы говорите, что отправляете заголовки при каждом запросе. Так в чем же разница?
joedotnot
3
Headersэто свойство отдельного HttpRequestMessageобъекта. Таким образом, вы можете создавать разные сообщения с разными заголовками. DefaultRequestHeadersявляется свойством HttpClientобъекта; если через данное сообщение отправлено несколько сообщений HttpClient, все такие сообщения будут одинаково DefaultRequestHeadersдобавлены к отдельным заголовкам сообщения.
Росс Прессер