Додавання заголовків під час використання httpClient.GetAsync


152

Я реалізую API, створений іншими колегами з Apiary.io, у проекті програми Windows Store.

Вони показують цей приклад методу, який я маю реалізувати:

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();
    }
}

У цьому та деяких інших методах мені потрібно мати заголовок із маркером, який я отримую раніше.

Ось зображення Поштальона (хромоване розширення) із заголовком, про який я говорю: введіть тут опис зображення

Як додати цей запит авторизації до запиту?



5
Попередження для потенційних шукачів коду: це неправильне використання HttpClient !! Перевірте aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong чому.
321X

Відповіді:


174

Під час використання GetAsync з HttpClient ви можете додати заголовки авторизації так:

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

Це додає заголовка авторизації протягом життя HttpClient, тому корисно, якщо ви потрапляєте на один сайт, де заголовок авторизації не змінюється.

Ось детальна відповідь


31
-1, оскільки HttpClient повинен бути багаторазовим (див. Aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong ). Якщо він повинен бути багаторазовим, встановлення заголовків запитів за замовчуванням є поганою практикою.
JCKödel

22
@ JCKödel Це хибне припущення, яке ви робите. Якщо ви завжди телефонуєте на той же сайт з однаковими обліковими даними протягом життя HttpClient за допомогою DefaultRequestHeaders, ви позбавляєте вас від необхідності постійно встановлювати їх знову з одними і тими ж значеннями. Вам слід перечитати ту статтю, в якій йдеться про використання одного і того ж екземпляра HttpClient, але вона не робить жодних заяв про те, що заголовки запитів за замовчуванням є поганою практикою. Якщо я телефоную лише одному сайту з HTTP-клієнтом, що на практиці відбувається за допомогою DefaultRequestHeaders, позбавляє вас від необхідності їх встановлювати кожен раз.
kmcnamee

@ JCKödel, хоч ви невірно вважаєте, але я підтримав ваш коментар, оскільки ви підняли важливий момент. У відповідь додано більшої чіткості.
Najeeb

@kmcnamee, що робити, якщо мені потрібно передати два жетони?
Najeeb

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);
}

5
Здається безпечнішим не використовувати DefaultRequestHeaders, якщо значення часто змінюється.
Джейсон Роу

3
Зауважте, що вам дуже ймовірно, що requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", your_token);"Носієм" буде недійсний заголовок HTTP
Кріс Марісіч

3
Дякую за це, ми повторно використовуємо наш HttpClient, і це нам допомогло
StevenMcD

2
@JCKodel це додало б шуму, тому що вам не потрібно використовувати, usingале ви можете створити екземпляр у конструкторі та розпоряджатися вDispose()
Philippe

3
Я ніколи не говорив про використання usingHttpClient (це погано), я сказав на HttpRequesMessage (тому що в ньому є некеровані буфери пам'яті для потокового передавання, ЯКІ ПОВИНЕН бути видалені після використання). Запит та відповідь мають бути розпоряджені кожним запитом (інакше ви тривалий час залишатиметеся великими шматками пам'яті). HttpClientМожна використовувати повторно, щоб розширити.
JCKödel

70

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

client.DefaultRequestHeaders.Add("Accept", "application/*+xml;version=5.1");
client.DefaultRequestHeaders.Add("Authorization", "Basic " + authstring);

Найпростіший спосіб додати заголовок Basic Authorization
sandyiit


4

Після відповіді 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")

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.