Utilizando HttpClient para Comunicação HTTP em C#

Ao desenvolver aplicações que interagem com serviços externos, como APIs de tradução ou sistemas de alerta, a comunicação HTTP é uma necessidade frequente. Em C#, a classe HttpClient, parte do namespace System.Net.Http, oferece uma maneira robusta e flexível de realizar requisições HTTP, tanto para operações GET quanto POST. Este artigo explora como encapsular e utilizar HttpClient de forma eficiente.

Encapsulando Operações HTTP

Para simplificar o uso de HttpClient e garantir uma estrutura de código limpa, podemos criar uma classe utilitária estática. Esta classe pode gerenciar a instância de HttpClient e fornecer métodos convenientes para as operações mais comuns.

Configuração Inicial

A instância de HttpClient deve ser configurada adequadamente. É recomendado utilizar um HttpClientHandler para gerenciar aspectos como o uso de cookies. A inicialização deve ocorrer uma única vez para reutilização, evitando a sobrecarga de criar novas instâncias repetidamente.


using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;

namespace MeuApp.Servicos
{
   public static class HttpHelper
   {
       private static readonly Uri BaseUri = new Uri("https://api.example.com/");
       private static readonly HttpClient client;

       static HttpHelper()
       {
           var handler = new HttpClientHandler
           {
               UseCookies = true // Habilita o uso de cookies
           };
           client = new HttpClient(handler)
           {
               BaseAddress = BaseUri
           };
           // Configurações adicionais como timeouts podem ser definidas aqui
           // client.Timeout = TimeSpan.FromSeconds(30);
       }

       public static async Task<string> GetAsync(string endpoint)
       {
           var response = await client.GetAsync(endpoint);
           response.EnsureSuccessStatusCode(); // Lança exceção para códigos de erro HTTP
           return await response.Content.ReadAsStringAsync();
       }

       public static async Task<string> PostAsync(string endpoint, Dictionary<string, string> formData)
       {
           var content = new FormUrlEncodedContent(formData);
           var response = await client.PostAsync(endpoint, content);
           response.EnsureSuccessStatusCode();
           return await response.Content.ReadAsStringAsync();
       }

       public static async Task<string> PostAsync(string endpoint, string jsonData)
       {
           var content = new StringContent(jsonData, System.Text.Encoding.UTF8, "application/json");
           var response = await client.PostAsync(endpoint, content);
           response.EnsureSuccessStatusCode();
           return await response.Content.ReadAsStringAsync();
       }
   }
}
   

Convenções de Nomenclatura e Estrutura

É uma boa prática organizar as chamadas de API em métodos específicos dentro de classes dedicadas, que podem, por sua vez, utilizar a classe utilitária HttpHelper. Por exemplo, uma operação de login pode ser encapsulada em um método dedicado.


using System.Collections.Generic;
using System.Threading.Tasks;

namespace MeuApp.Servicos
{
   public class AuthService
   {
       public async Task<LoginResult> AuthenticateAsync(Dictionary<string, string> credentials)
       {
           const string loginEndpoint = "auth/login";
           string rawResult = await HttpHelper.PostAsync(loginEndpoint, credentials);
           
           // Deserializar rawResult para LoginResult (implementação omitida)
           // Exemplo: var result = System.Text.Json.JsonSerializer.Deserialize<LoginResult>(rawResult);
           var result = new LoginResult { Successed = true, Message = "Login bem-sucedido" }; // Placeholder
           
           return result;
       }
   }

   public class ResultBase
   {
       public string ErrorCode { get; set; }
       public string Message { get; set; }
   }

   public class LoginResult : ResultBase
   {
       public bool Successed { get; set; }
       // Construtor e lógica de desserialização seriam adicionados aqui
   }
}
   

Tratametno de Respostas

Após receber uma resposta do servidor, é essencial processá-la. Isso pode envolver a desserialização de dados JSON, a verificação de códigos de status HTTP e a manipulação de mensagens de erro. A classe LoginResult, por exemplo, pode ser estendida para incluir a lógica de análise da resposta bruta.

Tags: httpclient C# HTTP APIs REST

Publicado em 7-20 11:33