Как правильно пользоваться заголовками HttpClient

В приложении один единственный экземпляр HttpClient

static readonly HttpClient client = new HttpClient();

Но есть куча методов запускаемые в разных потоках которые работают с HttpClient и задают ему заголовки. Иногда потоки пересекаются и получается что по несколько раз пытаются задать один и тот же заголовок и вылетает исключение.

    client.DefaultRequestHeaders.Clear();
    client.DefaultRequestHeaders.ExpectContinue = false;
    client.DefaultRequestHeaders.Add("UserAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36");
    client.DefaultRequestHeaders.Add("Accept-Charset", "utf-8;q=0.7,*;q=0.3");

Вот как сделать так, чтобы я мог менять заголовки, но не получал исключения xD

Т.е. для каждого запроса чтобы у меня были свои заголовки, пусть иногда они и одинаковые.

MSDN HttpClient.DefaultRequestHeaders


Ответы (1 шт):

Автор решения: aepot

DefaultRequestHeaders они на то и Default, что они по умолчанию. Они оптимизированы для быстродействия, то есть на добаление этих заголовоков в каждый запрос уйдет меньше времени, чем если вы будете добавлять их непосредственно в запрос. Чтобы добавить заголовок в запрос, можно использовать HttpRequestMessage.

К примеру, вам нужно выполнить GET запрос. Тогда метод получения страницы будет выглядеть примерно так:

static readonly HttpClient client = new HttpClient();

private async Task<string> GetHtmlPageAsync(string url)
{
    using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
    request.Headers.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36");
    request.Headers.AcceptCharset.ParseAdd("utf-8;q=0.7,*;q=0.3");
    using HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
    // response.EnsureSuccessStatusCode(); // бросает исключение если сервер вернул ошибку
    return await response.Content.ReadAsStringAsync();
}
→ Ссылка