如何在.NET(C#)中发送HTTP POST请求:从简单到复杂
\n\n想象一下,您的C#应用程序就像一个快递员,需要将包裹(数据)送到指定地址(URL)并获取确认(响应)。这正是HTTP POST请求要解决的问题。在Stack Overflow上,这个问题获得了数千次浏览,这并不奇怪:与外部API交互、发送表单、向服务器上传数据——这些都是任何.NET开发者的日常工作。
\n\n在本文中,我们将介绍在.NET(C#)中发送POST请求的三种主要方法,从现代的HttpClient到“老式”的WebRequest。您将学习如何传输JSON、URL编码数据、处理错误以及避免新手常遇到的陷阱。我们开始吧!
1. 现代方法:HttpClient(推荐)
\n\n从.NET Framework 4.5开始以及所有.NET Core / .NET 5+版本中,HttpClient类已成为事实上的标准。它专为异步工作而设计,支持连接复用,并且易于配置。
1.1. 简单的JSON POST(最常见场景)
\n\n假设我们需要以JSON格式将用户数据发送到服务器。实际代码如下所示:
\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. 将对象序列化为JSON\n var json = JsonSerializer.Serialize(newUser);\n var content = new StringContent(json, Encoding.UTF8, "application/json");\n\n // 2. 发送POST请求\n HttpResponseMessage response = await _httpClient.PostAsync("https://api.example.com/users", content);\n\n // 3. 读取响应\n response.EnsureSuccessStatusCode(); // 如果状态码不是2xx,则抛出异常\n\n var responseBody = await response.Content.ReadAsStringAsync();\n return JsonSerializer.Deserialize<UserResponse>(responseBody);\n }\n}\n\n// 使用示例\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 { Name = "伊万", Email = "ivan@example.com" };\n var result = await service.CreateUserAsync(user);\n Console.WriteLine($"已创建用户ID: {result.Id}");\n }\n}\n\npublic class UserDto\n{\n public string Name { get; set; }\n public string Email { get; set; }\n}\n\npublic class UserResponse\n{\n public int Id { get; set; }\n}\n\n重要提示:
\n- \n
- 始终使用
async/await——这可以防止线程被阻塞。 \n EnsureSuccessStatusCode()——是您快速检查错误的最佳帮手。 \n - 不要为每个请求创建新的
HttpClient——这会导致socket exhaustion(套接字耗尽)。在ASP.NET Core中使用IHttpClientFactory或使用单个静态实例。 \n
1.2. 使用表单数据POST(application/x-www-form-urlencoded)
\n\n有时API需要像普通HTML表单那样的数据格式。这时我们使用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