Добавление заголовков при использовании httpClient.GetAsync

153

Я реализую API, созданный другими коллегами с Apiary.io, в проекте приложения для Магазина Windows.

Они показывают этот пример метода, который я должен реализовать:

var baseAddress = new Uri("https://private-a8014-xxxxxx.apiary-mock.com/");

using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{
    using (var response = await httpClient.GetAsync("user/list{?organizationId}"))
    {
        string responseData = await response.Content.ReadAsStringAsync();
    }
}

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

Вот изображение Postman (расширение chrome) с заголовком, о котором я говорю: введите описание изображения здесь

Как добавить этот заголовок авторизации в запрос?

Ric
источник
2
возможный дубликат настройки заголовка авторизации HttpClient
Даниэль Келли
5
Предупреждение Для потенциальных поисковиков кода: это неправильное использование HttpClient !! Проверьте aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong почему.
321X

Ответы:

175

При использовании GetAsync с HttpClient вы можете добавить заголовки авторизации следующим образом:

httpClient.DefaultRequestHeaders.Authorization 
                         = new AuthenticationHeaderValue("Bearer", "Your Oauth token");

Это действительно добавляет заголовок авторизации на время жизни HttpClient, поэтому полезно, если вы заходите на один сайт, где заголовок авторизации не изменяется.

Вот подробный ТАК ответ

kmcnamee
источник
31
-1 потому что HttpClient должен быть многоразовым (см. Aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong ). Если он должен быть многоразовым, установка заголовков запросов по умолчанию является плохой практикой.
JCKödel
23
@ JCKödel Это ложное предположение, которое вы делаете. Если вы всегда вызываете один и тот же сайт с одними и теми же учетными данными в течение срока службы HttpClient с помощью DefaultRequestHeaders, это избавляет вас от необходимости постоянно устанавливать их снова с одинаковыми значениями. Вам следует перечитать ту статью, в которой говорится об использовании одного и того же экземпляра HttpClient, в нем нет никаких утверждений о том, что заголовки запросов по умолчанию являются плохой практикой. Если я вызываю только один сайт с HTTP-клиентом, что на практике происходит с использованием DefaultRequestHeaders, избавляет вас от необходимости устанавливать их каждый раз.
kmcnamee
@ JCKödel, хотя ты ошибаешься в своем предположении, я не одобрил твой комментарий, потому что ты поднял важный вопрос. Добавлена ​​большая ясность в ответ.
Наджиб
@kmcnamee, что если мне нужно передать два токена?
Наджиб
281

Более поздний ответ, но потому что никто не дал это решение ...

Если вы не хотите устанавливать заголовок в HttpClientэкземпляре, добавляя его в DefaultRequestHeaders, вы можете установить заголовки для каждого запроса .

Но вы будете обязаны использовать SendAsync()метод.

Это правильное решение, если вы хотите повторно использоватьHttpClient - что является хорошей практикой для

Используйте это так:

using (var requestMessage =
            new HttpRequestMessage(HttpMethod.Get, "https://your.site.com"))
{
    requestMessage.Headers.Authorization =
        new AuthenticationHeaderValue("Bearer", your_token);
    httpClient.SendAsync(requestMessage);
}
Philippe
источник
5
Кажется безопаснее не использовать DefaultRequestHeaders, если значение часто меняется.
Джейсон Роу
3
Обратите внимание, что вам, скорее всего, понадобится requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", your_token);«Носитель» - недопустимый заголовок HTTP
Крис Марисик,
3
Спасибо за это, мы повторно используем наш HttpClient, и это помогло нам
StevenMcD
2
@JCKodel это добавило бы шума, потому что вы не обязаны использовать, usingно можете создать экземпляр в конструкторе и расположить вDispose()
Philippe
3
Я никогда не говорил использовать usingна HttpClient (это плохо), я говорил на HttpRequesMessage (потому что у него есть неуправляемые буферы памяти для потоковой передачи, которые ДОЛЖНЫ быть удалены после использования). Запрос и ответ обрабатываются и должны обрабатываться при каждом запросе (в противном случае большие блоки памяти будут оставаться заблокированными в течение длительного времени). HttpClientМожно использовать повторно, чтобы расширить.
JCKödel
70

Принятый ответ работает, но может усложниться, если я захочу добавить заголовки Accept. Это то, что я закончил. Мне кажется это проще, поэтому я думаю, что буду придерживаться этого в будущем:

client.DefaultRequestHeaders.Add("Accept", "application/*+xml;version=5.1");
client.DefaultRequestHeaders.Add("Authorization", "Basic " + authstring);
sirdank
источник
Самый простой
7

Вы можете добавить любые заголовки, которые вам нужны HttpClient.

Вот хороший урок об этом.

Это не просто ссылка на POST-запросы, вы также можете использовать его для GET-запросов.

greenhoorn
источник
URL Github , в случае, если срок действия ссылки на сайт истек.
Сен Джейкоб
5

Следуя ответу Greenhoorn, вы можете использовать «Расширения» следующим образом:

  public static class HttpClientExtensions
    {
        public static HttpClient AddTokenToHeader(this HttpClient cl, string token)
        {
            //int timeoutSec = 90;
            //cl.Timeout = new TimeSpan(0, 0, timeoutSec);
            string contentType = "application/json";
            cl.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
            cl.DefaultRequestHeaders.Add("Authorization", String.Format("Bearer {0}", token));
            var userAgent = "d-fens HttpClient";
            cl.DefaultRequestHeaders.Add("User-Agent", userAgent);
            return cl;
        }
    }

И использовать:

string _tokenUpdated = "TOKEN";
HttpClient _client;
_client.AddTokenToHeader(_tokenUpdated).GetAsync("/api/values")
RDyego
источник
-1

Иногда вам нужен только этот код.

 httpClient.DefaultRequestHeaders.Add("token", token);
Джекдон Ван
источник