c# 如何进行http请求

11次阅读

应全局复用单个 httpClient 实例以避免内存泄漏和 socket 耗尽;GET 请求用 EnsureSuccessStatusCode() 自动校验状态码;POST jsON 时用 StringContent 设置 application/json 且省略 charset;超时用 CancellationToken 控制;绕过 ssl 验证仅限测试且需注意 handler 生命周期管理。

c# 如何进行http请求

HttpClient 发起最简 GET 请求

绝大多数场景下,直接用 HttpClient 就够了,它线程安全、支持连接池、能复用底层 TCP 连接。别每次请求都 new 一个实例——这是最常见的内存泄漏和 socket 耗尽源头。

正确做法是全局复用单个 HttpClient 实例(比如声明为 Static readonly 或注入到 DI 容器):

private static readonly HttpClient _client = new HttpClient();  public async Task GetContentAsync(string url) {     var response = await _client.GetAsync(url);     response.EnsureSuccessStatusCode();     return await response.Content.ReadAsStringAsync(); }

注意:EnsureSuccessStatusCode() 会在 HTTP 状态码非 2xx 时抛出 HttpRequestException,避免手动检查 response.IsSuccessStatusCode

POST JSON 数据并读取响应

发 JSON 是高频需求,关键在设置正确的 Content-Type 和序列化方式。.net 6+ 推荐用 System.Text.Json,轻量且无额外依赖。

  • HttpClient 默认不带 JSON 支持,需手动序列化 + 设置 StringContent
  • 别用 application/json; charset=utf-8 —— charset 在 JSON 媒体类型中是冗余且可能被某些服务拒绝的
  • 响应体同样建议用 ReadAsStringAsync()ReadAsByteArrayAsync(),避免阻塞线程
var data = new { Name = "Alice", Age = 30 }; var json = JsonSerializer.Serialize(data); var content = new StringContent(json, Encoding.UTF8, "application/json");  var response = await _client.PostAsync("https://api.example.com/users", content); var result = await response.Content.ReadAsStringAsync();

处理超时、重试和取消

生产环境必须控制请求生命周期。HttpClientTimeout 属性只作用于单次请求(包括 dns 解析、连接、发送、接收),不适用于整个异步操作链;更灵活的方式是传入 CancellationToken

  • TimeSpan.FromSeconds(10) 创建 token: var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
  • cts.Token 传给所有 GetAsync/PostAsync 调用
  • 如需自动重试,不要手写 while 循环——引入 Polly 库更可靠,尤其配合指数退避
  • 注意:CancellationToken 取消后,HttpClient 不会主动中断底层 socket,但会尽快退出等待并抛出 OperationCanceledException

绕过 SSL 证书验证(仅限测试)

开发时遇到自签名证书报错 AuthenticationException: The remote certificate is invalid,临时方案是配置 HttpClientHandlerServerCertificateCustomValidationCallback

var handler = new HttpClientHandler {     ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true }; var client = new HttpClient(handler);

这个回调返回 true 表示信任所有证书——上线前必须删掉,且不能用于任何生产或用户数据场景。真实项目应通过添加根证书或使用正式签发的域名证书解决。

真正容易被忽略的是:一旦用了自定义 HttpClientHandler,你就得自己管理它的生命周期;如果 handler 含有 unmanaged 资源(比如自定义 DNS 解析逻辑),没正确 dispose 会导致句柄泄露。

text=ZqhQzanResources