При отправке запросов с помощью HttpClient можно использовать ряд способов как для отправки, так и для получения заголовков. Но в любом случае нам придется работать с типом System.Net.Http.Headers, который представляет коллекцию заголовков. Для управления заголовками этот тип предоставляет ряд методов:
Add(String headerName, IEnumerable<String> values)
: добавляет указанный заголовок и его значения в коллекцию HttpHeaders
Add(String headerName, String headerValue)
: добавляет указанный заголовок и его значение в коллекцию HttpHeaders
Clear()
: удаляет все заголовки из коллекции HttpHeaders
Contains(String headerName)
: возвращает true, если определенный заголовок присутствует в коллекции HttpHeaders
Remove(String headerName)
: удаляет указанный заголовок из коллекции HttpHeaders
TryGetValues(String headerName, IEnumerable<String> values)
: возвращает коллекцию значений для указанного заголовка, если
он имеется в коллекции HttpHeaders
Этот класс абстрактный и реализуется классами HttpContentHeaders, HttpRequestHeaders и HttpResponseHeaders.
Прежде всего мы можем глобально настроить заголовки с помощью свойства DefaultRequestHeaders класс HttpClient. Это свойство представляет тип HttpRequestHeaders, то есть реализует все те же методы, что были указаны выше.
Например, пусть у нас есть следующее веб-приложение ASP.NET, которое получает два заголовка: стандартный "User-Agent" и кастомный "SecreteCode":
var builder = WebApplication.CreateBuilder(); var app = builder.Build(); app.MapGet("/", (HttpContext context) => { // пытаемся получить заголовок "SecreteCode" context.Request.Headers.TryGetValue("User-Agent", out var userAgent); // пытаемся получить заголовок "SecreteCode" context.Request.Headers.TryGetValue("SecreteCode", out var secreteCode); // отправляем данные обратно клиенту return $"User-Agent: {userAgent} SecreteCode: {secreteCode}"; }); app.Run();
Отправим заголовки из консольного приложения с помощью HttpClient:
class Program { static HttpClient httpClient = new HttpClient(); static async Task Main() { // адрес сервера var serverAddress = "https://localhost:7094/"; // устанавливаем оба заголовка httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla FIrefox 5.4"); httpClient.DefaultRequestHeaders.Add("SecreteCode", "hello"); using var response = await httpClient.GetAsync(serverAddress); var responseText = await response.Content.ReadAsStringAsync(); Console.WriteLine(responseText); } }
Стоит отметить, что для упрощения установки отдельных заголовков класс HttpRequestHeaders предоставляет ряд специальных свойств:
Accept
: возвращает значение заголовка Accept
AcceptCharset
: возвращает значение заголовка Accept-Charset
AcceptEncoding
: возвращает значение заголовка Accept-Encoding
AcceptLanguage
: возвращает значение заголовка Accept-Language
Authorization
: возвращает или задает значение заголовка Authorization
CacheControl
: возвращает или задает значение заголовка Cache-Control
Connection
: возвращает значение заголовка Connection
Date
: возвращает или задает значение заголовка Date
Expect
: возвращает значение заголовка Expect
From
: возвращает или задает значение заголовка From
Host
: возвращает или задает значение заголовка Host
IfMatch
: возвращает значение заголовка If-Match
IfModifiedSince
: возвращает или задает значение заголовка If-Modified-Since
IfNoneMatch
: возвращает значение заголовка If-None-Match
IfRange
: возвращает или задает значение заголовка If-Range
IfUnmodifiedSince
: возвращает или задает значение заголовка If-Unmodified-Since
MaxForwards
: возвращает или задает значение заголовка Max-Forwards
Pragma
: возвращает значение заголовка Pragma
ProxyAuthorization
: возвращает или задает значение заголовка Proxy-Authorization
Range
: возвращает или задает значение заголовка Range
Referrer
: возвращает или задает значение заголовка Referer
TE
: возвращает значение заголовка TE
Trailer
: возвращает значение заголовка Trailer
TransferEncoding
: возвращает значение заголовка Transfer-Encoding
Upgrade
: возвращает значение заголовка Upgrade
UserAgent
: возвращает значение заголовка User-Agent
Via
: возвращает значение заголовка Via
Warning
: возвращает значение заголовка Warning
Использование подобных свойств позволяет гарантировать, что при названии заголовка не допущена ошибка. Каждого подобное свойство представляет объект HttpHeaderValueCollection, который типизирует определенным типом - объект этого типа представляет значение заголовка. Например, установка "User-Agent":
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("User-Agent", "Mozilla FIrefox 5.4");
Если заголовка надо установить только для определенного запроса, то можно использовать свойство Headers класса HttpRequestMessage, которое также представляет тип HttpRequestHeaders:
class Program { static HttpClient httpClient = new HttpClient(); static async Task Main() { // адрес сервера var serverAddress = "https://localhost:7094/"; using var request = new HttpRequestMessage(HttpMethod.Get, serverAddress); // устанавливаем оба заголовка request.Headers.Add("User-Agent", "Mozilla Failfox 5.6"); request.Headers.Add("SecreteCode", "hello"); using var response = await httpClient.SendAsync(request); var responseText = await response.Content.ReadAsStringAsync(); Console.WriteLine(responseText); } }
Для получения заголовков, которые установил сервер, можно использовать свойство Headers класса HttpResponseMessage, которое представляет тип HttpResponseHeaders. Например, получим заголовок "date", который представляет дату обращения:
class Program { static HttpClient httpClient = new HttpClient(); static async Task Main() { var serverAddress = "https://localhost:7094/"; using var response = await httpClient.GetAsync(serverAddress); var dateValues = response.Headers.GetValues("Date"); Console.WriteLine(dateValues.FirstOrDefault()); } }
Стоит отметить, что, если заголовка с указанным именем не окажется в ответе, то приложение сгенерирует исключение. Чтобы избежать подобной ситуации, мы можем перед получением значения
заголовка проверять его наличие с помощью метода Contains()
(возвращает true, если заголовок имеется). Либо использовать метод TryGetValues(),
который возвращает true при успешном получении значений заголовка в выходной out-параметр. Но если заголовок отсутствует, то выходной параметр будет иметь значение null.
class Program { static HttpClient httpClient = new HttpClient(); static async Task Main() { var serverAddress = "https://localhost:7094/"; using var response = await httpClient.GetAsync(serverAddress); response.Headers.TryGetValues("date", out var dateValues); Console.WriteLine(dateValues?.FirstOrDefault()); } }
Также стоит отметить, что для упрощения получения распространенных заголовков класс HttpResponseHeaders предоставляет ряд специальных методов:
AcceptRanges
: возвращает значение заголовка Accept-Ranges
Age
: возвращает или задает значение заголовка Age
CacheControl
: возвращает или задает значение заголовка Cache-Control
Connection
: возвращает значение заголовка Connection
Date
: возвращает или задает значение заголовка Date
ETag
: возвращает или задает значение заголовка ETag
Location
: возвращает или задает значение заголовка Location
Pragma
: возвращает значение заголовка Pragma
ProxyAuthenticate
: возвращает значение заголовка Proxy-Authenticate
RetryAfter
: возвращает или задает значение заголовка Retry-After
Server
: возвращает значение заголовка Server
Trailer
: возвращает значение заголовка Trailer
TransferEncoding
: возвращает значение заголовка Transfer-Encoding
Upgrade
: возвращает значение заголовка Upgrade
Vary
: возвращает значение заголовка Vary
Via
: возвращает значение заголовка Via
Warning
: возвращает значение заголовка Warning
WwwAuthenticate
: возвращает значение заголовка WWW-Authenticate для HTTP-ответа.