Como enviar uma requisição HTTP POST em .NET com C#: do simples ao avançado
\n\nImagine que sua aplicação em C# é um entregador que precisa levar um pacote (dados) para um endereço específico (URL) e receber uma confirmação (resposta). Essa é exatamente a função de uma requisição HTTP POST. No Stack Overflow, esse tópico acumula milhares de visualizações, e não é à toa: integração com APIs externas, envio de formulários, upload de dados para servidores — tudo isso faz parte da rotina de qualquer desenvolvedor .NET.
\n\nNeste artigo, vamos explorar três formas principais de enviar uma requisição POST em .NET (C#), começando pelo moderno HttpClient até o clássico WebRequest. Você aprenderá a transmitir JSON, dados codificados em URL, tratar erros e evitar as armadilhas comuns para iniciantes. Vamos nessa!
1. Abordagem moderna: HttpClient (recomendado)
\n\nA partir do .NET Framework 4.5 e em todas as versões do .NET Core / .NET 5+, a classe HttpClient se tornou o padrão de fato. Ela foi projetada para operações assíncronas, suporta reutilização de conexões e é altamente configurável.
1.1. POST simples com JSON (cenário mais comum)
\n\nSuponha que precisamos enviar dados de um usuário para o servidor no formato JSON. Veja como fica no código real:
\n\nusing System;\nusing System.Net.Http;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading.Tasks;\n\npublic class UserService\n{\n private readonly HttpClient _httpClient;\n\n public UserService(HttpClient httpClient)\n {\n _httpClient = httpClient;\n }\n\n public async Task<UserResponse> CreateUserAsync(UserDto newUser)\n {\n // 1. Serializa o objeto para JSON\n var json = JsonSerializer.Serialize(newUser);\n var content = new StringContent(json, Encoding.UTF8, "application/json");\n\n // 2. Envia o POST\n HttpResponseMessage response = await _httpClient.PostAsync("https://api.exemplo.com/usuarios", content);\n\n // 3. Lê a resposta\n response.EnsureSuccessStatusCode(); // Lança exceção se o status não for 2xx\n\n var responseBody = await response.Content.ReadAsStringAsync();\n return JsonSerializer.Deserialize<UserResponse>(responseBody);\n }\n}\n\n// Exemplo de uso\npublic class Program\n{\n public static async Task Main()\n {\n var client = new HttpClient();\n var service = new UserService(client);\n \n var user = new UserDto { Nome = "João", Email = "joao@exemplo.com" };\n var result = await service.CreateUserAsync(user);\n Console.WriteLine($"Usuário criado com ID: {result.Id}");\n }\n}\n\npublic class UserDto\n{\n public string Nome { get; set; }\n public string Email { get; set; }\n}\n\npublic class UserResponse\n{\n public int Id { get; set; }\n}\n\nPontos importantes:
\n- \n
- Sempre use
async/await— isso evita que a thread seja bloqueada. \n EnsureSuccessStatusCode()— seu melhor amigo para verificar erros rapidamente. \n - Não crie um novo
HttpClientpara cada requisição — isso causa socket exhaustion (esgotamento de sockets). UseIHttpClientFactoryno ASP.NET Core ou uma instância estática. \n
1.2. POST com dados de formulário (application/x-www-form-urlencoded)
\n\nÀs vezes, a API exige dados no formato de um formulário HTML comum. Para isso, usamos FormUrlEncodedContent:
public async Task<string> PostFormDataAsync(string username, string password)\n{\n var formData = new Dictionary<string, string>\n {\n { "grant_type", "password" },\n { "username", username },\n { "password", password }\n };\n\n var content = new FormUrlEncodedContent(formData);\n\n using var client = new HttpClient();\n var response = awa