Skip to content

HttpClient 终极实战指南

在 .NET 生态中,HttpClient 早已成为官方推荐的 HTTP 请求标准方案,而老旧的 WebRequestHttpWebRequestWebClient 等类已被标记为过时(Obsolete)

相比自己封装 HttpHelper 帮助类,HttpClient 原生支持异步、连接池管理、请求/响应封装,无需重复造轮子,用法极简且性能更优。本文整理 HttpClient 最全实战用法,覆盖日常开发 99% 场景,直接复制即用!

一、核心前言:为什么必须用 HttpClient?

  1. 官方替代方案:.NET Framework 4.5+ / .NET Core 全平台支持,旧版 HTTP 相关类已弃用,不再维护更新;
  2. 性能更优:内置 HTTP 连接池,复用 TCP 连接,避免频繁创建销毁请求导致的性能损耗;
  3. 用法极简:原生封装 Get/Post/Put/Delete 等请求,无需手动处理请求头、流、编码等繁琐逻辑;
  4. 功能全面:支持 Cookie、请求头、文件上传、超时、取消请求、JSON 交互等所有场景。

❌ 禁忌:不要在方法内频繁 new HttpClient()!正确用法是单例/静态实例,或通过依赖注入(DI)注入,避免套接字耗尽。

二、基础准备:推荐的标准初始化方式

1. 最佳实践:依赖注入(ASP.NET Core 首选)

csharp
// Program.cs 中注册单例 HttpClient
builder.Services.AddHttpClient();

// 业务类中通过构造函数注入使用
private readonly HttpClient _httpClient;
public YourService(HttpClient httpClient)
{
    _httpClient = httpClient;
}

2. 通用场景:静态单例(控制台/WinForms/WPF)

csharp
// 全局定义一个静态实例,整个程序共用
public static class HttpHelper
{
    public static readonly HttpClient Instance = new HttpClient
    {
        Timeout = TimeSpan.FromSeconds(10) // 统一设置超时
    };
}

三、高频实战用法

1. 基础 GET 请求

异步为默认推荐用法,HttpClient 所有核心方法均为异步,禁止滥用 .Result 阻塞线程

csharp
// 1. 获取响应字符串
string url = "https://api.example.com/getdata";
string responseStr = await HttpHelper.Instance.GetStringAsync(url);

// 2. 获取完整响应信息(状态码、响应头、响应体)
HttpResponseMessage response = await HttpHelper.Instance.GetAsync(url);
// 验证请求是否成功
response.EnsureSuccessStatusCode(); 
// 获取状态码
HttpStatusCode statusCode = response.StatusCode;
// 获取响应字符串
string result = await response.Content.ReadAsStringAsync();

2. GET 请求下载文件/字节数组

适用于下载图片、视频、文件等二进制数据:

csharp
string fileUrl = "https://example.com/video.mp4";
// 异步获取文件字节数组
byte[] fileBytes = await HttpHelper.Instance.GetByteArrayAsync(fileUrl);

// 保存到本地文件
string savePath = "test.mp4";
await File.WriteAllBytesAsync(savePath, fileBytes);

通过 HttpClientHandler 配置 Cookie 容器,适用于需要登录态/身份验证的请求:

csharp
// 1. 创建处理器并配置Cookie
var handler = new HttpClientHandler
{
    // 自动处理Cookie(可选)
    UseCookies = true,
    CookieContainer = new CookieContainer()
};

// 2. 添加Cookie
Uri targetUri = new Uri("https://api.example.com");
handler.CookieContainer.Add(targetUri, new Cookie("token", "123456"));
handler.CookieContainer.Add(targetUri, new Cookie("userId", "1001"));

// 3. 初始化带Cookie的HttpClient
using var client = new HttpClient(handler);
// 4. 添加通用请求头
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0");
client.DefaultRequestHeaders.Add("Connection", "keep-alive");

// 发送请求
string result = await client.GetStringAsync(targetUri);

4. POST 请求(两大常用格式)

① 表单提交:application/x-www-form-urlencoded

最常用的表单参数提交方式,兼容传统接口:

csharp
string url = "http://192.168.0.9:9000/Demo/PostUrlCode";

// 构造表单参数
var formData = new Dictionary<string, string>
{
    { "name", "小明" },
    { "age", "20" }
};

// 发送POST请求
var response = await HttpHelper.Instance.PostAsync(
    url, 
    new FormUrlEncodedContent(formData)
);

// 读取响应结果
string result = await response.Content.ReadAsStringAsync();

② JSON 请求:application/json(现代接口首选)

csharp
string url = "https://api.example.com/submit";
// 构造请求对象
var postData = new { Name = "小明", Age = 20 };

// 序列化JSON + 设置请求类型
var jsonContent = new StringContent(
    JsonSerializer.Serialize(postData),
    Encoding.UTF8,
    "application/json"
);

// 发送请求
var response = await HttpHelper.Instance.PostAsync(url, jsonContent);
string result = await response.Content.ReadAsStringAsync();

5. 文件上传(多文件+参数)

支持单文件/多文件上传,同时携带普通表单参数:

csharp
string uploadUrl = "http://192.168.1.108:56852/api/Test/SaveFile";
string filePath = Path.Combine(Environment.CurrentDirectory, "1.png");

// 构造 multipart 表单数据
using var multipartContent = new MultipartFormDataContent();
// 1. 添加普通字符串参数
multipartContent.Add(new StringContent("123456"), "qq");
// 2. 添加文件参数(参数名,文件名)
multipartContent.Add(
    new ByteArrayContent(await File.ReadAllBytesAsync(filePath)), 
    "file", 
    "123.png"
);

// 发送上传请求
var response = await HttpHelper.Instance.PostAsync(uploadUrl, multipartContent);
string result = await response.Content.ReadAsStringAsync();

6. 请求超时 + 取消请求

两种方式控制请求超时,支持手动取消请求:

csharp
// 方式1:全局设置默认超时时间
HttpHelper.Instance.Timeout = TimeSpan.FromSeconds(10);

// 方式2:单次请求单独取消(CancellationToken)
var cts = new CancellationTokenSource();
// 10秒后自动取消请求
cts.CancelAfter(TimeSpan.FromSeconds(10));

try
{
    string result = await HttpHelper.Instance.GetStringAsync(
        "https://api.example.com", 
        cts.Token
    );
}
catch (TaskCanceledException)
{
    Console.WriteLine("请求超时或已取消");
}
最近更新