WebAPI-Filter

WebAPI-Filter

内置过滤器

在ASP.NET Core中,过滤器(Filters)用于在执行控制器操作之前或之后执行特定的逻辑。它们是MVC管道的一部分,可以帮助开发者处理诸如验证请求、日志记录、异常处理等跨切面关注点。ASP.NET Core支持多种类型的过滤器,每种都有其特定的作用场景。以下是一些主要的过滤器类型及其用途:

  • 授权过滤器(Authorization Filters)

    • 作用:这类过滤器最早运行,主要用于检查用户是否有权限访问给定的操作。

    • 示例:使用[Authorize]属性来确保只有经过身份验证的用户才能访问某个控制器或动作方法。

  • 资源过滤器(Resource Filters)

    • 作用:这些过滤器在模型绑定之前运行,并且可以取消操作的执行。如果资源过滤器决定阻止请求,则不会执行模型绑定、操作过滤器或结果过滤器。

    • 示例:可以用来实现缓存逻辑,例如检查缓存中是否存在请求的数据,如果存在则直接返回缓存数据,不再执行后续操作。

  • 操作过滤器(Action Filters)

  • 作用:这类过滤器允许你在操作方法执行前或执行后进行干预。它们可以用来修改输入或输出参数。

  • 示例:验证模型状态,如果模型状态无效,则返回错误信息而不调用操作方法。

  • 异常过滤器(Exception Filters)

    • 作用:用于捕获并处理在整个MVC管道中发生的未处理异常。

    • 示例:可以用来记录异常信息,并向客户端返回友好的错误响应。

  • 结果过滤器(Result Filters)

    • 作用:在操作执行完毕后,但在结果执行前后运行。它们可以用来修改操作的结果,比如修改视图或格式化响应。

    • 示例:压缩响应内容,或者添加特定的HTTP头信息。


自定义过滤器

自定义过滤器可以通过实现 IFilterMetadata 接口或继承预定义的过滤器类(如 ActionFilterAttributeResultFilterAttributeExceptionFilterAttribute 等)来创建


自定义操作过滤器
using Microsoft.AspNetCore.Mvc.Filters;
using System;

public class SampleActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("SampleActionFilter: Action is about to execute.");
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("SampleActionFilter: Action has executed.");
        base.OnActionExecuted(context);
    }
}

以上代码可以通过OnActionExecutionAsync方法实现

using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;

public class SampleActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // 在动作方法执行前执行的逻辑
        Console.WriteLine("SampleActionFilter: Action is about to execute.");

        // 调用下一个过滤器或动作方法
        var resultContext = await next();

        // 在动作方法执行后执行的逻辑
        Console.WriteLine("SampleActionFilter: Action has executed.");
    }
}

自定义异常过滤器
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using System;

public class SampleExceptionFilter : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        Console.WriteLine($"SampleExceptionFilter: Exception caught: {context.Exception.Message}");

        context.Result = new ObjectResult(new { error = "An unexpected error occurred" })
        {
            StatusCode = 500
        };

        base.OnException(context);
    }
}

注册过滤器

无论是内置过滤器或自定义过滤器都可以通过 services.AddMvcservices.AddControllersWithViews 方法中的 options.Filters 属性进行注册

  • 全局注册:在 Startup.csProgram.cs 中全局注册过滤器。

  • 控制器级别注册:在控制器类上使用属性来注册过滤器。

  • 动作级别注册:在控制器的动作方法上使用属性来注册过滤器。

有三种添加全局过滤器的方式

// AddMvc方式
builder.Services.AddMvc(options =>
{
    options.Filters.Add<SampleActionFilter>();
});

// AddControllersWithViews方式
builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<SampleActionFilter>();
});

// Configure<MvcOptions>方式
builder.Services.Configure<MvcOptions>(options =>
{
    options.Filters.Add<SampleActionFilter>();
});

总结

ASP.NET Core 和JavaWeb项目中的过滤器不同,这里的过滤器更像是一个跟生命周期钩子有关的AOP(面向切面编程)的一个增强类,通过不同的注册方式来服务于Controller层的日志记录、异常处理、权限验证等功能

例如,我们可以通过操作过滤器(Action Filters)来实现SpringAOP的功能,在具体实现代码的前后做一些切面操作