ASP.NET Core 中,操作过滤器(Action Filters)

ASP.NET Core 中,操作过滤器(Action Filters)用于在控制器的操作方法执行之前或之后执行自定义逻辑。操作过滤器主要用于在请求到达控制器方法之前进行处理(例如:验证请求参数、设置数据)、在操作执行后处理响应(例如:记录日志、修改响应结果)等。

操作过滤器的工作原理

操作过滤器可以通过实现IActionFilter 接口或继承ActionFilterAttribute 来创建。它们可以用于对操作方法的输入和输出进行拦截,在执行请求之前或之后进行特定操作。

操作过滤器的执行时机是:

  • 执行前:在控制器操作方法执行之前。
  • 执行后:在控制器操作方法执行之后,但在返回结果给客户端之前。

操作过滤器的实现方式

1. 使用IActionFilter 接口

你可以通过实现IActionFilter 接口来创建一个自定义的操作过滤器。IActionFilter 接口包含两个方法:

  • OnActionExecuting(ActionExecutingContext context):在操作方法执行之前调用。
  • OnActionExecuted(ActionExecutedContext context):在操作方法执行之后调用。
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;

publicclassMyActionFilter : IActionFilter
{
    privatereadonly ILogger<MyActionFilter> _logger;

    public MyActionFilter(ILogger<MyActionFilter> logger)
    {
        _logger = logger;
    }

    // 在操作执行之前调用
    public void OnActionExecuting(ActionExecutingContext context)
    {
        _logger.LogInformation("OnActionExecuting: {ActionName}", context.ActionDescriptor.DisplayName);
        // 你可以在这里进行请求参数的验证或其他预处理操作
    }

    // 在操作执行之后调用
    public void OnActionExecuted(ActionExecutedContext context)
    {
        _logger.LogInformation("OnActionExecuted: {ActionName}", context.ActionDescriptor.DisplayName);
        // 在这里进行操作后的处理(例如:修改结果、记录日志等)
    }
}

2. 使用ActionFilterAttribute 特性类

ASP.NET Core 还提供了一个基类ActionFilterAttribute,它实现了IActionFilter 接口。你可以通过继承这个类来创建自定义的操作过滤器。这样,你就可以通过特性标记来应用过滤器。

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;

publicclassMyActionFilterAttribute : ActionFilterAttribute
{
    privatereadonly ILogger<MyActionFilterAttribute> _logger;

    public MyActionFilterAttribute(ILogger<MyActionFilterAttribute> logger)
    {
        _logger = logger;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        _logger.LogInformation("OnActionExecuting: {ActionName}", context.ActionDescriptor.DisplayName);
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        _logger.LogInformation("OnActionExecuted: {ActionName}", context.ActionDescriptor.DisplayName);
        base.OnActionExecuted(context);
    }
}

3. 应用操作过滤器

  • 应用于控制器或操作方法:你可以通过[ServiceFilter] 或[TypeFilter] 特性将自定义的操作过滤器应用于特定的控制器或方法。

    • 使用ActionFilterAttribute 的方式:

      [MyActionFilterAttribute]
      public class HomeController : Controller
      {
          public IActionResult Index()
          {
              return View();
          }
      }
    • 使用ServiceFilter 或TypeFilter 特性来注入服务:

      [ServiceFilter(typeof(MyActionFilter))]
      public class HomeController : Controller
      {
          public IActionResult Index()
          {
              return View();
          }
      }

      ServiceFilter 用于注入已注册的服务类型;TypeFilter 允许指定一个类型,可以通过构造函数来创建。

4. 在Startup.cs 中注册操作过滤器

如果你想全局使用自定义的操作过滤器,可以在Startup.cs 文件中的ConfigureServices 方法中进行注册:

public void ConfigureServices(IServiceCollection services)
{
    // 注册自定义过滤器
    services.AddScoped<MyActionFilter>(); // 如果你使用了 ServiceFilter 特性,记得注册依赖注入

    // 全局添加过滤器
    services.AddControllersWithViews(options =>
    {
        options.Filters.Add<MyActionFilter>(); // 这会将 MyActionFilter 应用到所有控制器和操作
    });
}

操作过滤器的使用场景

操作过滤器的使用场景非常广泛,通常用来处理以下任务:

  1. 日志记录:记录每个请求的相关信息。

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        _logger.LogInformation($"Executing action {context.ActionDescriptor.DisplayName}");
    }
  2. 验证请求数据:例如,验证请求的参数是否符合预期。

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var parameter = context.ActionArguments["id"];
        if (parameter == null || (int)parameter <= 0)
        {
            context.Result = new BadRequestObjectResult("Invalid ID");
        }
    }
  3. 修改响应结果:操作方法执行后,可以对返回的结果进行修改。

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        if (context.Result is ViewResult viewResult)
        {
            viewResult.ViewData["CustomData"] = "This is added by the filter.";
        }
    }
  4. 缓存处理:为请求添加缓存逻辑。

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var cacheKey = GenerateCacheKey(context);
        var cachedData = _cache.Get(cacheKey);
        if (cachedData != null)
        {
            context.Result = new JsonResult(cachedData);
        }
    }
  5. 权限检查:例如检查当前用户是否具有访问某些资源的权限。

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!_userHasPermission)
        {
            context.Result = new ForbidResult();
        }
    }

异步操作过滤器

如果你需要在操作执行前或后执行异步操作(如访问数据库或外部 API),你可以实现IAsyncActionFilter 接口。它有两个方法:

  • OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next):该方法是异步的,允许你在执行操作前或后进行异步操作。
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

publicclassMyAsyncActionFilter : IAsyncActionFilter
{
    privatereadonly ILogger<MyAsyncActionFilter> _logger;

    public MyAsyncActionFilter(ILogger<MyAsyncActionFilter> logger)
    {
        _logger = logger;
    }

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        _logger.LogInformation("OnActionExecutionAsync: Before Action Execution");
        
        // 执行操作之前的逻辑(如果需要)
        var resultContext = await next();  // 调用控制器操作方法

        _logger.LogInformation("OnActionExecutionAsync: After Action Execution");

        // 执行操作之后的逻辑(如果需要)
    }
}

小结

  • 操作过滤器 是在控制器方法执行之前或之后执行自定义逻辑的强大工具。
  • 你可以通过实现IActionFilter 或继承ActionFilterAttribute 类来创建操作过滤器。
  • 操作过滤器可以用于多种场景,如日志记录、参数验证、响应修改、权限检查等。
  • 它们可以通过[ServiceFilter][TypeFilter][ActionFilter] 特性应用到单个控制器或操作,也可以在Startup.cs 中配置为全局过滤器。
  • 异步操作过滤器(IAsyncActionFilter)适用于需要执行异步操作的场景。

使用操作过滤器可以将额外的逻辑从控制器中抽离出来,使得代码更加清晰和易于维护。

 
posted @   跟着阿笨一起玩.NET  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
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种人
点击右上角即可分享
微信分享提示