C# HTTP客户端:正确高效地发送请求

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么需要在 C# 中使用合适的 HTTP 客户端

在现代开发中,几乎没有任何应用程序可以不与外部服务交互而正常运行。无论是向服务器发送数据、获取货币汇率,还是与云 API 协作——所有这些都需要正确实现 HTTP 请求。在 C# (.NET) 生态系统中,完成此任务的主要工具是 HttpClient 类。然而,许多开发者,尤其是初学者,会犯一些典型错误:为每个请求创建新的 HttpClient 实例、忘记处理异常或异步操作使用不当。

本文将详细讲解如何正确组织 C# 中的 HTTP 客户端,介绍发送 GET 和 POST 请求、处理请求头和请求体,以及错误处理的最佳实践。阅读本文后,您将能够编写可靠且高性能的代码来与任何 REST API 进行交互。



C# 中 HttpClient 的基础知识

HttpClient 类是 System.Net.Http 命名空间的一部分,可在所有现代版本的 .NET(Core、5、6、7、8 及以上版本)中使用。其主要优势在于支持异步操作和自动连接池管理。



正确创建 HttpClient

最重要的规则:不要为每个请求创建新的 HttpClient。这可能导致套接字耗尽。相反,应为整个应用程序生命周期使用单个实例,或使用 IHttpClientFactory。

// ❌ 错误:为每个请求创建新的 HttpClientusing (var client = new HttpClient()){    var response = await client.GetAsync("https://api.example.com");}

// ✅ 正确:为所有请求使用同一个 HttpClientpublic class MyHttpService{ private static readonly HttpClient _client = new HttpClient(); public async Task<string> GetDataAsync(string url) { return await _client.GetStringAsync(url); }}


基本配置

初始化 HttpClient 时,可以设置基础地址、超时时间和默认请求头:

public class ApiClient{    private readonly HttpClient _httpClient;        public ApiClient()    {        _httpClient = new HttpClient        {            BaseAddress = new Uri("https://api.pythonlib.ru/"),            Timeout = TimeSpan.FromSeconds(10)        };                // 每次请求都会发送的请求头        _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");        _httpClient.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");    }}


发送 GET 和 POST 请求

让我们来看看两种最常见的 HTTP 请求类型:获取数据(GET)和发送数据(POST)。



GET 请求:获取数据

GET 请求用于从服务器读取数据。它不应更改资源状态,也不包含请求体。

public async Task<string> GetUserAsync(int userId){    try    {        var response = await _httpClient.GetAsync($"/api/users/{userId}");        response.EnsureSuccessStatusCode(); // 出错时会抛出异常        return await response.Content.ReadAsStringAsync();    }    catch (HttpRequestException ex)    {        Console.WriteLine($"请求错误:{ex.Message}");        throw;    }}

对于简单情况,可以使用简写形式:

string json = await _httpClient.GetStringAsync("/api/users/42");


POST 请求:发送数据

POST 请求用于创建新资源。数据通过请求体发送,通常采用 JSON 格式。

public async Task<User> CreateUserAsync(User newUser){    // 将对象序列化为 JSON    var json = JsonSerializer.Serialize(newUser);                

博客

书籍推荐