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 类。
  • 异常过滤器可以帮助集中处理应用中的错误,定制错误响应,并进行日志记录。
  • 在配置时,可以选择将异常过滤器应用于单个控制器、操作方法,或全局应用于所有控制器。
  • 异常过滤器有助于改进应用的容错性和用户体验,确保即使发生错误,用户也能得到友好的错误提示。
posted @   跟着阿笨一起玩.NET  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 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种人
点击右上角即可分享
微信分享提示