引言:为什么在 C# 中正确的 HTTP 客户端很重要
在现代 C# (.NET) 开发中,处理 HTTP 请求是一项基本需求。无论是调用 REST API、从 Web 服务器下载数据,还是与云服务集成,都离不开一个可靠的 HTTP 客户端。然而,许多开发者,尤其是初学者,会犯一些典型错误:不正确的连接管理、忽略超时设置或低效的响应处理。在本文中,我们将从基础到高级技术,详细讲解如何在 C# 中创建 HTTP 客户端。
我们将重点介绍 HttpClient 类——这是 .NET 中处理 HTTP 的主要工具,同时也会探讨其他替代方案。您将学习如何正确发送 GET 和 POST 请求、处理 JSON、管理标头以及避免常见的性能问题。
基础:创建和配置 HttpClient
正确初始化 HttpClient
HttpClient 类被设计为可重复使用。为每个请求创建一个新实例是一种反模式,可能导致套接字耗尽。相反,应在整个应用程序中使用单个实例,或通过 IHttpClientFactory 进行依赖注入 (DI)。
// 错误做法:为每个请求创建新实例public async Task<string> BadRequest(string url){ using (var client = new HttpClient()) { return await client.GetStringAsync(url); }}
// 正确做法:使用静态实例public static readonly HttpClient SharedClient = new HttpClient();
// 或通过 IHttpClientFactory(推荐用于 ASP.NET Core)services.AddHttpClient("MyClient", client =>{ client.BaseAddress = new Uri("https://api.example.com"); client.DefaultRequestHeaders.Add("Accept", "application/json");});配置超时和基地址
超时设置可以保护应用程序在服务器不可用时不会挂起。HttpClient 有自己的超时设置,但您可以覆盖它。
HttpClient client = new HttpClient{ BaseAddress = new Uri("https://jsonplaceholder.typicode.com"), Timeout = TimeSpan.FromSeconds(10) // 整个请求的超时时间为 10 秒};设置 MaxResponseContentBufferSize 来限制接收数据的大小也很有用。
发送请求:GET、POST、PUT 和 DELETE
GET 请求:获取数据
获取数据最简单的方法是使用 GetStringAsync 或 GetAsync 并手动处理响应。
public async Task<string> GetUsersAsync(){ HttpResponseMessage response = await SharedClient.GetAsync("/users"); response.EnsureSuccessStatusCode(); // 出错时抛出异常 return await response.Content.ReadAsStringAsync();}
// 或者更简单的方式:string json = await SharedClient.GetStringAsync("/users");POST 请求:发送数据
要发送 JSON,请使用 PostAsJsonAsync(需要 System.Net.Http.Json 包)。
var newUser = new { name = "伊万", email = "ivan@example.com" };HttpResponseMessage response = await SharedClient.PostAsJsonAsync("/users", newUser);if (response.IsSuccessStatusCode){ var createdUser = await response.Content.ReadFromJsonAsync<User>();}要发送表单,请使用 FormUrlEncodedContent。
var formData = new Dictionary<string, string>{ { "username", "admin" }, { "password", "secret" }};var content = new FormUrlEncodedContent(formData);HttpResponseMessage response = await SharedClient.PostAsync("/login", content);PUT 和 DELETE 请求
更新和删除操作类似:
// PUTvar updateData = new { id = 1, name = "更新后的名称" };HttpResponseMessage putR