ASP.NET Core 中,异常过滤器(Exception Filters)
在ASP.NET Core 中,异常过滤器(Exception Filters)用于捕获控制器或操作方法中的未处理异常,并对其进行处理、记录、转换或返回特定的错误响应。异常过滤器可以帮助你集中处理应用程序中的所有异常,提供一致的错误处理机制,同时避免暴露详细的错误信息给客户端,提升系统的健壮性和安全性。
异常过滤器的工作原理
异常过滤器是ASP.NET Core MVC 框架的一部分,它会在控制器的操作方法执行过程中,如果发生未处理的异常时被触发。异常过滤器允许开发者对异常进行捕获、处理和定制错误响应。与其他类型的过滤器(如操作过滤器、授权过滤器)不同,异常过滤器的作用是捕获并处理应用程序中的异常,确保即使发生错误,应用也能优雅地响应。
异常过滤器的实现
1. 实现IExceptionFilter
接口
要实现自定义的异常过滤器,最常见的方式是通过实现IExceptionFilter
接口。这个接口有一个方法OnException
,该方法会在控制器操作方法抛出异常时执行。你可以在OnException
方法中编写异常处理逻辑。
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
publicclassCustomExceptionFilter : IExceptionFilter
{
privatereadonly ILogger<CustomExceptionFilter> _logger;
public CustomExceptionFilter(ILogger<CustomExceptionFilter> logger)
{
_logger = logger;
}
public void OnException(ExceptionContext context)
{
// 捕获到异常后,记录日志
_logger.LogError(context.Exception, "An error occurred in the application.");
// 可以通过上下文修改返回的错误响应
context.Result = new Microsoft.AspNetCore.Mvc.JsonResult(new
{
message = "An error occurred, please try again later."
})
{
StatusCode = 500// 设置 HTTP 状态码
};
// 设置异常已被处理
context.ExceptionHandled = true;
}
}
2. 使用ExceptionFilterAttribute
特性
如果你不想手动实现IExceptionFilter
接口,可以继承ExceptionFilterAttribute
类来实现异常过滤器。这样,你可以将异常过滤器作为一个特性直接应用到控制器或操作方法。
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
publicclassCustomExceptionFilterAttribute : ExceptionFilterAttribute
{
privatereadonly ILogger<CustomExceptionFilterAttribute> _logger;
public CustomExceptionFilterAttribute(ILogger<CustomExceptionFilterAttribute> logger)
{
_logger = logger;
}
public override void OnException(ExceptionContext context)
{
// 捕获到异常后,记录日志
_logger.LogError(context.Exception, "An error occurred in the application.");
// 可以通过上下文修改返回的错误响应
context.Result = new Microsoft.AspNetCore.Mvc.JsonResult(new
{
message = "An error occurred, please try again later."
})
{
StatusCode = 500// 设置 HTTP 状态码
};
// 设置异常已被处理
context.ExceptionHandled = true;
}
}
3. 在控制器或操作方法中应用异常过滤器
你可以通过在控制器或操作方法上应用[ServiceFilter]
或[TypeFilter]
特性来使用自定义的异常过滤器。
在控制器级别应用:
[ServiceFilter(typeof(CustomExceptionFilter))]
public class HomeController : Controller
{
public IActionResult Index()
{
throw new InvalidOperationException("This is a test exception.");
}
}
在全局应用:
如果你希望全局应用异常过滤器,可以在Startup.cs
中的ConfigureServices
方法中进行配置。
public void ConfigureServices(IServiceCollection services)
{
// 注册自定义的异常过滤器
services.AddScoped<CustomExceptionFilter>();
services.AddControllersWithViews(options =>
{
// 将异常过滤器应用到所有控制器和操作方法
options.Filters.Add(typeof(CustomExceptionFilter));
});
}
4. 异常过滤器的优先级
- 执行顺序:异常过滤器是在所有操作方法执行之后、返回结果之前执行的。如果异常被
IExceptionFilter
捕获并处理,其他后续的过滤器将不再执行。 - ExceptionHandled 标志:你需要显式地设置
context.ExceptionHandled = true
,以告诉框架该异常已经被处理。如果不设置,框架将继续向上传递该异常,直到找到适当的处理程序。
5. 异常过滤器与全局异常处理
异常过滤器和全局异常处理中间件(如UseExceptionHandler
)在某些情况下可以一起使用,但两者的作用有所不同:
- 异常过滤器:在 MVC 请求处理过程中捕获异常,并允许开发者通过修改
ExceptionContext
来处理异常。 - 全局异常处理中间件:通常在管道中较早的阶段执行(如在
Configure
方法中配置),用于处理未处理的异常。它通常用于捕获整个应用程序中的异常,返回一个友好的错误页面或日志。
全局异常处理中间件示例:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// 捕获全局未处理的异常
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
}
6. 常见的异常处理场景
1.记录异常
你可以通过异常过滤器来记录所有发生的异常,特别是在生产环境中,日志记录对于问题的追踪非常重要。
public void OnException(ExceptionContext context)
{
_logger.LogError(context.Exception, "An error occurred in the application.");
context.ExceptionHandled = true;
}
2.定制错误响应
当捕获到异常时,通常我们需要返回一个定制的错误响应,而不是 ASP.NET Core 默认的错误页面。你可以修改context.Result
来设置响应内容。
public void OnException(ExceptionContext context)
{
context.Result = new JsonResult(new { message = "An unexpected error occurred." })
{
StatusCode = 500 // 设置返回的 HTTP 状态码
};
context.ExceptionHandled = true;
}
3.返回不同类型的错误响应
根据异常的类型或其他条件,返回不同的 HTTP 状态码或响应内容。例如,如果是客户端错误,可以返回 400 错误:
public void OnException(ExceptionContext context)
{
if (context.Exception is ArgumentException)
{
context.Result = new JsonResult(new { message = "Invalid input." })
{
StatusCode = 400// 设置 HTTP 400 错误
};
}
else
{
context.Result = new JsonResult(new { message = "An unexpected error occurred." })
{
StatusCode = 500
};
}
context.ExceptionHandled = true;
}
7. 异常过滤器的优缺点
优点:
- 集中化错误处理:你可以在一个地方处理所有的异常,避免在多个控制器或操作方法中重复处理错误。
- 定制化错误响应:可以根据不同的异常类型返回不同的错误响应,使得客户端能够根据错误类型进行相应的处理。
- 日志记录:可以轻松地在异常发生时记录详细的日志,帮助调试和诊断问题。
缺点:
- 可能会隐藏某些错误:如果异常没有被正确处理或记录,可能会导致一些错误被“吞掉”,使得开发者不容易发现潜在问题。
- 全局处理可能不适用:有时候,某些异常可能需要特定的处理逻辑,使用全局异常过滤器可能不适合所有场景。
总结
- 异常过滤器 在ASP.NET Core 中用于捕获并处理控制器操作方法中的未处理异常。
- 实现自定义异常过滤器时,你可以通过实现
IExceptionFilter
接口或继承ExceptionFilterAttribute
类。 - 异常过滤器可以帮助集中处理应用中的错误,定制错误响应,并进行日志记录。
- 在配置时,可以选择将异常过滤器应用于单个控制器、操作方法,或全局应用于所有控制器。
- 异常过滤器有助于改进应用的容错性和用户体验,确保即使发生错误,用户也能得到友好的错误提示。
作者:阿笨
【官方QQ一群:跟着阿笨一起玩NET(已满)】:422315558
【官方QQ二群:跟着阿笨一起玩C#(已满)】:574187616
【官方QQ三群:跟着阿笨一起玩ASP.NET(已满)】:967920586
【官方QQ四群:Asp.Net Core跨平台技术开发(可加入)】:829227829
【官方QQ五群:.NET Core跨平台开发技术(可加入)】:647639415
【网易云课堂】:https://study.163.com/provider/2544628/index.htm?share=2&shareId=2544628
【51CTO学院】:https://edu.51cto.com/sd/66c64
【微信公众号】:微信搜索:跟着阿笨一起玩NET
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2021-02-04 SQL Server数据库高级进阶之事务实战演练
2021-02-04 C#如何正确运用异步编程技术
2021-02-04 SQL Server数据库高级进阶之锁实战演练
2020-02-04 .NET Core基于SQL Server数据库主从同步实现读写分离实战演练
2013-02-04 将要被社会淘汰的8种人