C# 全局异常处理方法 C#在ASP.NET Core中如何实现全局异常处理

来源:这里教程网 时间:2026-02-21 17:40:38 作者:

ASP.NET Core 中用
UseExceptionHandler
捕获未处理异常

ASP.NET Core 不再支持传统的

Global.asax
Application_Error
,全局异常必须在中间件管道中注册。最标准的做法是调用
UseExceptionHandler
,它会拦截所有未被
try/catch
捕获的异常,并重定向到指定的错误处理路径(如
/error
)或直接返回响应。

关键点:

UseExceptionHandler
必须放在
UseRouting
之后、
UseEndpoints
之前,否则无法生效
它只捕获 HTTP 请求生命周期内的异常,不处理后台任务(如
HostedService
)或应用启动阶段的异常
默认返回状态码 500,但响应体内容可自定义(JSON、HTML 或纯文本)
app.UseExceptionHandler("/error"); // 重定向到控制器路由
// 或
app.UseExceptionHandler(exceptionHandlerApp =>
{
    exceptionHandlerApp.Run(async context =>
    {
        context.Response.StatusCode = StatusCodes.Status500InternalServerError;
        context.Response.ContentType = "application/json";
        var ex = context.Features.Get<IExceptionHandlerFeature>()?.Error;
        await context.Response.WriteAsJsonAsync(new { error = ex?.Message });
    });
});

/error
控制器里获取原始异常信息

使用路径方式(如

/error
)时,需确保对应控制器能从
IExceptionHandlerFeature
中提取异常详情。这个 Feature 只在
UseExceptionHandler("/error")
触发的请求中存在,普通请求里取不到。

常见疏漏:

忘记添加
[Route("error")]
或路由匹配失败,导致进不了该 Action
直接读
HttpContext.Request.Query
Body
试图找异常 —— 错,必须用
context.Features.Get<iexceptionhandlerfeature>()</iexceptionhandlerfeature>
没检查
Feature?.Error
是否为 null,导致空引用异常
[Route("error")]
public class ErrorController : ControllerBase
{
    [HttpGet]
    public IActionResult HandleError()
    {
        var feature = HttpContext.Features.Get<IExceptionHandlerFeature>();
        var ex = feature?.Error;
        if (ex == null) return Problem("Unknown error", statusCode: 500);
        // 生产环境避免暴露堆栈,开发环境可加
        var response = new { message = ex.Message, stack = Environment.IsDevelopment() ? ex.StackTrace : null };
        return Problem(detail: ex.Message, statusCode: 500);
    }
}

如何区分开发/生产环境并控制错误输出粒度

直接把

Exception.StackTrace
InnerException
返回给前端,在生产环境属于严重安全风险。ASP.NET Core 提供了
Environment.IsDevelopment()
和内置的
ProblemDetails
标准化结构,应配合使用。

建议做法:

开发环境:返回完整
StackTrace
+
InnerException
,便于调试
生产环境:仅返回泛化错误消息(如 "An unexpected error occurred"),日志记录完整异常 避免在 JSON 响应中拼接
ex.ToString()
,它包含敏感类型名和路径

日志记录必须独立做,不能依赖

UseExceptionHandler
的响应逻辑。推荐在
HandleError
方法开头就调用
_logger.LogError(ex, "Unhandled exception")

全局异常处理不覆盖的三种典型场景

UseExceptionHandler
很强大,但不是万能的。以下三类异常它完全捕获不到,必须单独处理:

Startup.ConfigureServices
阶段抛出的异常 —— 应用根本起不来,需靠宿主日志(如 Windows Event Log 或
dotnet run
控制台输出)排查
后台服务(
IHostedService
)中未捕获的异常 —— 这些运行在独立线程,需在
ExecuteAsync
内自行
try/catch
并记录
终结点路由前的异常(如
UseHttpsRedirection
中证书验证失败)—— 发生在中间件链更早位置,可能绕过
UseExceptionHandler

尤其要注意 HTTPS 重定向失败时,浏览器可能直接显示“连接被重置”,而服务端日志里没有任何异常记录 —— 这类问题得查

Kestrel
日志级别或启用
Microsoft.AspNetCore.Server.Kestrel
的 Debug 级别日志。

相关推荐