Something beautiful is on the way.

.NET HttpClient 使用汇总

一、HttpClient 简介

HttpClient 是 .NET 中用于发送 HTTP 请求和接收 HTTP 响应的主要类,自 .NET 8 起有一些新特性和改进,下面是详细用法介绍。

二、基本用法

1. 创建 HttpClient 实例
// 方式一:直接创建(不推荐长期使用,可能导致套接字耗尽)
using var httpClient = new HttpClient();

// 方式二:使用 IHttpClientFactory(推荐)
// 需要在 DI 容器中注册(如 ASP.NET Core 中)
services.AddHttpClient();

// 在服务中注入使用
public class MyService
{
    private readonly HttpClient _httpClient;
    
    public MyService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
}

// 方式三:命名客户端
services.AddHttpClient("GitHub", client =>
{
    client.BaseAddress = new Uri("https://api.github.com/");
    client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    client.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
});

// 获取命名客户端
var githubClient = serviceProvider.GetRequiredService<IHttpClientFactory>().CreateClient("GitHub");
2. 发送 GET 请求
// 方式一:获取字符串结果
var httpClient = new HttpClient();
string responseBody = await httpClient.GetStringAsync("https://api.example.com/data");
Console.WriteLine(responseBody);

// 方式二:获取 JSON 并反序列化为对象
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("https://api.example.com/users/1");
response.EnsureSuccessStatusCode(); // 确保请求成功

string json = await response.Content.ReadAsStringAsync();
var user = JsonSerializer.Deserialize<User>(json);

// 方式三:直接反序列化(.NET 7+ 支持)
var user = await httpClient.GetFromJsonAsync<User>("https://api.example.com/users/1");
3. 发送 POST 请求
// 方式一:发送 JSON 数据
var httpClient = new HttpClient();
var user = new { Name = "John", Age = 30 };
var jsonContent = new StringContent(
    JsonSerializer.Serialize(user),
    Encoding.UTF8,
    "application/json");

var response = await httpClient.PostAsync("https://api.example.com/users", jsonContent);
response.EnsureSuccessStatusCode();

// 方式二:发送表单数据
var formContent = new FormUrlEncodedContent(new[]
{
    new KeyValuePair<string, string>("username", "testuser"),
    new KeyValuePair<string, string>("password", "testpass")
});

var response = await httpClient.PostAsync("https://api.example.com/login", formContent);
4. 发送 PUT/PATCH/DELETE 请求
// PUT 请求示例
var httpClient = new HttpClient();
var updatedUser = new { Name = "Updated Name", Age = 31 };
var jsonContent = new StringContent(
    JsonSerializer.Serialize(updatedUser),
    Encoding.UTF8,
    "application/json");

var response = await httpClient.PutAsync("https://api.example.com/users/1", jsonContent);

// DELETE 请求示例
var httpClient = new HttpClient();
var response = await httpClient.DeleteAsync("https://api.example.com/users/1");
5. 处理文件上传
var httpClient = new HttpClient();
using var formContent = new MultipartFormDataContent();

// 添加文件
var fileStream = File.OpenRead("path/to/file.jpg");
var fileContent = new StreamContent(fileStream);
formContent.Add(fileContent, "file", "file.jpg");

// 添加其他字段
formContent.Add(new StringContent("description"), "description");

var response = await httpClient.PostAsync("https://api.example.com/upload", formContent);

三、.NET 8 新增特性

1. HTTP/3 支持
// 配置 HttpClient 使用 HTTP/3
var httpClientHandler = new SocketsHttpHandler
{
    EnableMultipleHttp2Connections = true,
    PreferHttp3 = true // 启用 HTTP/3
};

var httpClient = new HttpClient(httpClientHandler);
2. 请求/响应压缩增强
// 自动处理压缩
var httpClientHandler = new SocketsHttpHandler
{
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli
};

var httpClient = new HttpClient(httpClientHandler);
3. 改进的超时处理
// 配置请求超时
var httpClient = new HttpClient
{
    Timeout = TimeSpan.FromSeconds(30) // 全局超时设置
};

// 针对特定请求设置超时
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var response = await httpClient.GetAsync("https://api.example.com/data", cts.Token);
4. 原生 AOT 支持
// .NET 8 支持 HttpClient 在原生 AOT 编译的应用中使用
// 需要确保正确配置序列化和反射
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(User))]
public void SomeMethod()
{
    var httpClient = new HttpClient();
    var user = await httpClient.GetFromJsonAsync<User>("https://api.example.com/users/1");
}

四、高级用法

1. 自定义消息处理程序
// 创建自定义消息处理程序
public class CustomHeaderHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // 添加自定义请求头
        request.Headers.Add("X-Custom-Header", "value");
        
        // 执行请求
        var response = await base.SendAsync(request, cancellationToken);
        
        // 处理响应
        if (response.StatusCode == HttpStatusCode.Unauthorized)
        {
            // 处理未授权情况
        }
        
        return response;
    }
}

// 注册自定义处理程序
var httpClientHandler = new SocketsHttpHandler();
var customHandler = new CustomHeaderHandler { InnerHandler = httpClientHandler };
var httpClient = new HttpClient(customHandler);
2. 处理 cookies
// 创建带有 Cookie 容器的 HttpClient
var handler = new SocketsHttpHandler
{
    UseCookies = true,
    CookieContainer = new CookieContainer()
};

var httpClient = new HttpClient(handler);

// 发送请求,自动处理 cookies
var response = await httpClient.GetAsync("https://example.com");
3. 流式处理大响应
var httpClient = new HttpClient();
using var response = await httpClient.GetAsync("https://example.com/large-file", HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();

using var stream = await response.Content.ReadAsStreamAsync();
using var fileStream = File.Create("path/to/save/file");
await stream.CopyToAsync(fileStream);

五、最佳实践

  1. 使用 IHttpClientFactory:避免手动管理 HttpClient 实例的生命周期,防止套接字耗尽问题。

  2. 配置超时:始终为请求设置合理的超时时间,防止长时间阻塞。

  3. 处理异常:使用 try/catch 块捕获并处理可能的网络异常。

  4. 启用压缩:配置 AutomaticDecompression 以提高性能。

  5. 管理连接:对于需要高并发的场景,调整 SocketsHttpHandler 的 MaxConnectionsPerServer 属性。

  6. 日志记录:在生产环境中启用 HttpClient 日志记录以帮助诊断问题。

以上是 .NET 8 中 HttpClient 的常见用法和新增特性,根据具体需求可以灵活组合使用这些功能。

posted @ 2025-05-29 18:01  张朋举  阅读(392)  评论(1)    收藏  举报