Back-End

26 mar, 2019

.NET Core: classe HttpClient (C#) – Parte 01

Publicidade

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:

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