在C#中使用HttpClient调用接口时,网络不通、DNS解析失败或服务器返回非成功状态码都可能触发HttpRequestException。理解它的抛出时机并正确捕获,是编写稳定HTTP客户端程序的基础。

HttpRequestException是什么
HttpRequestException位于System.Net.Http命名空间,是HttpClient在执行请求过程中发生错误时抛出的异常类型。它通常包裹了更底层的网络错误,例如连接被拒绝、域名无法解析等。需要注意的是,默认情况下即使服务器返回404或500,HttpClient也不会抛出HttpRequestException,而是返回对应的HttpResponseMessage,只有确保请求成功的方法才会抛异常。
基础捕获方式
最直接的做法是使用try-catch包裹请求代码,捕获HttpRequestException类型:
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
HttpClient client = new HttpClient();
try
{
// 使用EnsureSuccessStatusCode会在非2xx状态时抛出HttpRequestException
HttpResponseMessage resp = await client.GetAsync("https://ipipp.com/api/test");
resp.EnsureSuccessStatusCode();
string body = await resp.Content.ReadAsStringAsync();
Console.WriteLine(body);
}
catch (HttpRequestException ex)
{
// 捕获HTTP请求相关异常
Console.WriteLine("请求发生错误: " + ex.Message);
}
}
}
区分不同错误原因
HttpRequestException的InnerException往往包含真实的错误来源。可以通过判断内部异常类型来细分处理:
- SocketException:通常表示网络层连接失败
- TaskCanceledException:可能是超时或主动取消
- AuthenticationException:TLS握手失败
结合状态码的业务处理
如果未调用EnsureSuccessStatusCode,应手动判断StatusCode:
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
class Demo
{
static async Task CallApi()
{
HttpClient client = new HttpClient();
HttpResponseMessage resp = await client.GetAsync("https://ipipp.com/api/user");
if (resp.StatusCode == HttpStatusCode.NotFound)
{
Console.WriteLine("资源不存在");
}
else if (!resp.IsSuccessStatusCode)
{
Console.WriteLine("其他错误: " + resp.StatusCode);
}
}
}
超时与取消异常
HttpClient可设置Timeout属性,超时后会抛出TaskCanceledException而非HttpRequestException。建议分开捕获:
using System;
using System.Net.Http;
using System.Threading.Tasks;
class TimeoutDemo
{
static async Task RequestWithTimeout()
{
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(3);
try
{
await client.GetAsync("https://ipipp.com/slow");
}
catch (TaskCanceledException)
{
Console.WriteLine("请求超时");
}
catch (HttpRequestException ex)
{
Console.WriteLine("请求异常: " + ex.Message);
}
}
}
最佳实践建议
| 场景 | 推荐做法 |
|---|---|
| 必须保证成功响应 | 使用EnsureSuccessStatusCode并捕获HttpRequestException |
| 需要细粒度控制 | 不抛异常,手动判断StatusCode |
| 弱网环境 | 捕获HttpRequestException与TaskCanceledException分别处理 |
通过合理的异常捕获分层,你可以让C#的HTTP客户端在面对复杂网络状况时依然保持良好的可维护性。
C#HttpRequestExceptionHTTP客户端修改时间:2026-07-25 20:51:28