Neste artigo volto a apresentar a classe HttpClient com foco na plataforma .NET Core.
A classe HttpClient é usada para enviar uma requisição HTTP e receber a resposta da solicitação. Ela está presente mo namespace System.Net.Http, e as classes neste namespace tornam mais fácil consumir serviços da Web para clientes e servidores.
A classe HttpClient deriva da classe HttpMessageInvoker, e essa classe base implementa o método SendAsync. O método SendAsync é o cavalo de batalha da classe HttpClient.
Como veremos neste artigo, existem vários derivados desse método para usar. Como o nome indica, o método SendAsync faz uma chamada assíncrona, e isso permite que você escreva um sistema totalmente assíncrono para chamar serviços da web.
A classe HttpClient implementa a interface IDisposable e, como diretriz geral, objetos que implementam IDisposable devem ser descartados após seu uso – isso também vale para a classe HttpClient.
No entanto, o método Dispose do HttpClient não libera imediatamente o soquete associado – ele é liberado após um tempo limite, que pode levar 20 segundos.
Com esse tempo limite, usar muitas instâncias de objeto HttpClient pode fazer com que o programa fique sem sockets.
A solução: a classe HttpClient foi criada para reutilização. Assim, você pode usar essa classe com muitas requisições e não criar uma nova instância a cada vez.
Fazendo uma requisição GET Assíncrona
Vamos criar um projeto do tipo Console App (.NET Core) chamado NetCoreHttpClient e realizar uma chamada assíncrona com GET para acessar dados de um serviço da web.
Como exemplo, vou acessar os serviços disponibilizados nas seguintes URLs:
- 1. http://services.groupkt.com/country/get/all: retorna uma lista de países no formato JSON;
- 2. http://services.groupkt.com/country/get/iso2code/BR: retorna países pelo ISO Code;
O código completo do projeto é o seguinte:
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace NetCoreHttpClient
{
class Program
{
private const string listaPaisesUrl = "http://services.groupkt.com/country/get/all";
private const string paisesUrl = "http://services.groupkt.com/country/get/iso2code/BR";
private static HttpClient _httpClient;
private static HttpClient HttpClient => _httpClient ?? (_httpClient = new HttpClient());
static void Main(string[] args)
{
Task.Run(async () =>
{
await GetDadosWebServiceAsync();
}).GetAwaiter().GetResult();
Console.ReadLine();
}
public static async Task GetDadosWebServiceAsync()
{
HttpResponseMessage response = await HttpClient.GetAsync(paisesUrl);
if (response.IsSuccessStatusCode)
{
Console.WriteLine($"Status Code do Response : {(int)response.StatusCode} {response.ReasonPhrase}");
string responseBodyAsText = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Recebidos payload de {responseBodyAsText.Length} caracteres");
Console.WriteLine();
Console.WriteLine(responseBodyAsText);
}
}
}
}
Vamos entender o código:
- 1. Começamos definindo as constantes das URLs dos serviços REST que vamos acessar
- 2. Instanciamos um objeto HttpClient e o atribuímos ao campo privado _httpClient para reuso
Como o objeto HttpClient é thread-safe, um único objeto pode ser usado para tratar múltiplas requisições, pois cada instância de HttpClient mantém seu próprio pool de threads. Dessa forma, os requests entre instâncias de HttClient são isoladas.
- 3. A seguir, ajustamos o método Main() para poder usar o await e invocar o método GetDadosWebServiceAsycn() e poder marcar o método com async
A partir da versão 7.1 da C#, foi implementada uma forma de fazer isso conforme mostrado a seguir:
static async Task Main(string[] args)
{
await GetDadosWebServiceAsync();
Console.ReadLine();
}
- 4. No método chamado usamos o método GetAsync(), que retorna um objeto HttpResponseMessage. A classe HttpResponseMessage representa um response incluindo headers, status e conteúdo
- 5. Verificamos a propriedade IsSuccessfulStatusCode do response para saber se o request foi bem sucedido
- 6. Com a chamada feita com sucesso, o conteúdo é retornado como uma string usando o método ReadAsStringAsync()
Como a classe HttpClient usou a chamada do método GetAsync com a palavra-chave await, a thread chamada é retornada.
Quando o resultado estiver disponível no método GetAsync, um encadeamento continua com o método e a resposta é gravada na variável response.
Abaixo temos o resultado da execução do código:
Na segunda parte do artigo veremos como tratar exceções.
Pegue o projeto aqui: NetCoreHttpClient.zip