Introdução: por que você precisa de um cliente HTTP correto em C#
No desenvolvimento moderno na plataforma .NET, praticamente nenhuma aplicação fica sem interagir com servidores remotos. Seja obtendo dados de uma API REST, enviando formulários para um servidor web ou baixando arquivos — tudo isso requer uma implementação adequada de requisições HTTP. Em C#, existem várias abordagens, mas a mais moderna e recomendada é a classe HttpClient do namespace System.Net.Http. Neste artigo, vamos analisar como criar corretamente um cliente HTTP em C#, evitar erros típicos e escrever código eficiente.
Classes principais para trabalhar com HTTP em C# (.NET)
Antes de passar para os exemplos, é importante entender quais ferramentas a plataforma .NET oferece. As classes principais são:
- HttpClient — a classe principal para enviar requisições e receber respostas. Ela deve ser usada como um singleton (uma única instância para toda a aplicação).
- HttpRequestMessage — permite configurar detalhadamente a requisição: método, cabeçalhos, corpo, versão do protocolo.
- HttpResponseMessage — contém a resposta do servidor: status, cabeçalhos, corpo.
- HttpContent — classe base para representar o corpo de uma requisição ou resposta (por exemplo,
StringContent,ByteArrayContent,MultipartFormDataContent).
Regra fundamental: não crie uma nova instância de HttpClient para cada requisição. Isso leva ao esgotamento de sockets e à redução de desempenho. Use uma única instância estática ou injetada.
Configuração do HttpClient: exemplo básico
Vamos considerar uma configuração mínima. Criaremos uma instância de HttpClient e definiremos um endereço base:
using System;using System.Net.Http;using System.Threading.Tasks;
public class ApiService{ private static readonly HttpClient client = new HttpClient();
public ApiService() { client.BaseAddress = new Uri("https://api.example.com/"); client.DefaultRequestHeaders.Add("User-Agent", "C# HttpClient App"); client.DefaultRequestHeaders.Accept.Add( new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); }
public async Task<string> GetDataAsync(string endpoint) { HttpResponseMessage response = await client.GetAsync(endpoint); response.EnsureSuccessStatusCode(); // Lançará uma exceção em caso de erro return await response.Content.ReadAsStringAsync(); }}Observe o response.EnsureSuccessStatusCode() — esta é uma maneira simples de verificar se a requisição foi bem-sucedida (código 2xx).
Exemplos práticos de requisições HTTP em C#
Agora vamos para cenários específicos. Abordaremos requisições GET e POST, bem como o trabalho com cabeçalhos e tratamento de erros.
1. Requisição GET com parâmetros
Para passar parâmetros na string de consulta, você pode usar a coleção QueryHelpers de Microsoft.AspNetCore.WebUtilities ou simplesmente formar a URL manualmente. Abaixo um exemplo com formação manual:
public async Task<string> SearchUsersAsync(string name, int page){ var query = $"/users?name={Uri.EscapeDataString(name)}&page={page}"; HttpResponseMessage response = await client.GetAsync(query); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync();}Sempre use Uri.EscapeDataString() para escapar os parâmetros, a fim de evitar erros com caracteres especiais.
2. Requisição POST com corpo JSON
Para enviar dados no formato JSON, é conveniente usar a biblioteca System.Text.Json (ou Newtonsoft.Json). Convertemos o objeto para JSON e enviamos:
using System.Text;using System.Text.Json;
public