C# - Como incluir headers no request com HttpClient
Hoje veremos como podemos incluir headers no request usando o HttpClient em uma aplicação C#. |
A classe
HttpClient do namespace System.Net.Http envia requests HTTP e recebe responses
HTTP de um recurso identificado por uma URI.
A recomendação de uso deste recurso é usar uma instância HttpClient estática ou singleton com PooledConnectionLifetime definido para o intervalo desejado, como dois minutos, dependendo das alterações de DNS esperadas. Isso resolve os problemas de esgotamento de porta e alterações de DNS sem adicionar a sobrecarga de IHttpClientFactory. Se você precisar zombar de seu manipulador, poderá registrá-lo separadamente.
Usando IHttpClientFactory, você pode ter vários clientes configurados de forma diferente para diferentes casos de uso. No entanto, esteja ciente de que os clientes criados pela factory devem ter vida curta e, uma vez que o cliente é criado, a fábrica não tem mais controle sobre ele.
Para mais detalhes veja o artigo : ASP.NET Core - Usando o HttpClientFactory
Incluindo Headers do request
Exitem duas maneiras de incluir headers em um request usando o HttpClient:
Vamos iniciar com a primeira forma.
1- Incluindo um header imutável para todos os requests
Digamos que você
esteja adicionando um header de chave de API. Ele precisa ser incluído em todas
os requests e o valor não será alterado.
Para adicionar esse header no request, você pode usar
HttpClient.DefaultRequestHeaders ao inicializar a instância HttpClient,
da seguinte forma :
public
class
ServiceNumerosAleatorios { private readonly HttpClient HttpClient; private const string key = "xyz@123"; public ServiceNumerosAleatorios() { HttpClient = new HttpClient(); HttpClient.DefaultRequestHeaders.Add("ApiKey", key); } public async Task<string> GetNumeroAleatorio() { var response = await HttpClient.GetAsync(GetNumeroAleatorioUrl); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } } |
A seguir temos o resultado no Fiddler :
GET https://localhost:12345/NumeroAleatorio HTTP/1.1
Host: localhost:12345
ApiKey: xyz@123
|
2 - Adicionar um cabeçalho por request
Para adicionar um cabeçalho por request, usamos
HttpRequestMessage.Headers + HttpClient.SendAsync(), assim:
public
class
ServiceNumerosAleatorios { private readonly HttpClient HttpClient; private const string numeroAleatorioUrl = "https://localhost:12345/NumeroAleatorio"; public ServiceNumerosAleatorios() { HttpClient = new HttpClient(); } public async Task<string> GetRandomNumber(string Token) { using (var request = new HttpRequestMessage(HttpMethod.Get, numeroAleatorioUrl)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Token); var response = await HttpClient.SendAsync(request); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } } } |
Em primeiro lugar
é uma prática recomendada usar uma única instância HttpClient para vários
request. Como você está usando uma única instância, não use
HttpClient.DefaultRequestHeaders para cabeçalhos
que precisam ser aplicados por request. Não é thread-safe. É por isso que você
deve usar HttpRequestMessage.Headers.
Em segundo lugar, você deve usar HttpClient.SendAsync()
para enviar a solicitação porque não há sobrecargas de
GetAsync() / PostAsync() que usam um parâmetro
HttpRequestMessage.
Usando o método
GetWithHeadersAsync() para headers por request
Os métodos HttpClient.GetAsync() / PostAsync() são
métodos de conveniência. Seria bom se houvesse sobrecargas deles que aceitassem
uma lista de headers por request, mas não há.
Se você não quiser ter HttpRequestMessage + SendAsync()
em todo lugar, você pode abstrair essa lógica usando métodos de extensão. Aqui
está um exemplo:
public
static
class
HttpClientExtensions { public static async Task<HttpResponseMessage> GetWithHeadersAsync( this HttpClient httpClient, string requestUri, Dictionary<string, string> headers) { using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri)) { foreach (var header in headers) { request.Headers.Add(header.Key, header.Value); } return await httpClient.SendAsync(request); } } } |
Podemos usar o método de extensão de maneira semelhante ao GetAsync():
public
async
Task<string>
GetNumeroAleatorio(string
Token) { var response = await HttpClient.GetWithHeadersAsync(numeroAleatorioUrl, new Dictionary<string, string>() { ["Authorization"] = $"Bearer {Token}" }); response.EnsureSuccessStatusCode(); } |
Este é apenas um método de extensão e podemos usar isso como ponto de partida e a seguir adicionar métodos de extensão para todas as possíveis sobrecargas de GetAsync() ou PostAsync().
Usar as propriedades HttpRequestHeaders para adicionar
cabeçalhos comuns
Você pode adicionar qualquer cabeçalho usando .Add(key,
value). Para cabeçalhos comuns, como Authorization,
você também pode adicionar o cabeçalho por meio de propriedades em
HttpRequestHeaders. Isso pode ajudá-lo a evitar
erros e melhorar a legibilidade.
Por exemplo, podemos adicionar o cabeçalho Authorization nestas duas formas equivalentes:
//opção 1 request.Headers.Add("Authorization", $"Bearer {Token}"); //Opção 2 - Usando o a propriedade header request.Headers.Authorization = new AuthenticationHeaderValue(scheme: "Bearer", parameter: Token); |
E estamos conversados...
"O sumo sacerdote lhe tornou a perguntar, e
disse-lhe: És tu o Cristo, Filho do Deus Bendito?
E Jesus disse-lhe: Eu o
sou, e vereis o Filho do homem assentado à direita do poder de Deus, e vindo
sobre as nuvens do céu."
Marcos 14:61-62
Referências:
NET - Unit of Work - Padrão Unidade de ...