.Net Core ActionFilter

发布时间 2023-07-08 20:11:32作者: qfccc


作用

  • 在请求AuthorizeFilter -> ResourceFilter -> ActionFilter, 可以记录Action的日志
  • ActionFilter 在控制器实例化之后执行
  • ResourceFilter 可以在全局, Controller, Action 都可以设置, 并且都会执行(一个ResourceFilter可以重复设置)

如果都设置执行顺序为:

  1. 全局
  2. Controller
  3. Action
  4. Action 方法
  5. Action
  6. Controller
  7. 全局

实现

IActionFilter

  1. 需要继承 Attribute 并 并实现 IActionFilter
  2. 实现接口方法

执行顺序为:

  1. OnActionExecuting
  2. Action
  3. OnActionExecuted

IAsyncActionFilter

  1. 需要继承 Attribute 并 并实现 IAsyncActionFilter
  2. 实现接口方法
  3. 该接口只提供一个 OnActionExecutionAsync方法,如果想执行ActionExecutedContext方法,需要执行方法中ActionExecutionDelegate委托并取返回值然后代码在执行为
    ActionExecutedContext方法

执行顺序为:

  1. OnActionExecuting
  2. Action
  3. OnActionExecuted

ActionFilterAttribute

  1. 需要继承 ActionFilterAttribute
  2. 重写 OnActionExecuting OnActionExecuted OnResultExecuting OnResultExecuted 方法

执行顺序为:

  1. OnActionExecuting
  2. Action
  3. OnActionExecuted
  4. OnResultExecuting
  5. OnResultExecuted

Aop Action执行

过滤器代码

using Microsoft.AspNetCore.Mvc.Filters;

namespace Cnpc.Com.Ioc.WebApp.Filter.ActionFilter
{
    public class CustomAsyncActionFilter : Attribute, IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            {
                Console.WriteLine("ActionExecutingContext.....");
            }
            ActionExecutedContext executed = await next();
            {
                Console.WriteLine("ActionExecutedContext.....");
            }
        }
    }
}

Action代码

using Cnpc.Com.Ioc.WebApp.Filter;
using Microsoft.AspNetCore.Mvc;

namespace Cnpc.Com.Ioc.WebApp.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestFilterController : ControllerBase
    {
        //[TypeFilter(typeof(CustomAsyncActionFilter))]  如果想在ActionFilter支持Nlog 并使用构造注入就这样写
        [CustomAsyncActionFilter]
        [HttpGet]
        public async Task Action_AsyncActionFilter()
        {
            Console.WriteLine("Func...");
            await Task.CompletedTask;
        }
    }
}

使用日志

Action

//[ServiceFilter(typeof(CustomAsyncActionFilter))] 如果使用SerciceFilter 要先将CustomAsyncActionFilter 注册到ioc中
[TypeFilter(typeof(CustomAsyncActionFilter))] //如果想在ActionFilter支持Nlog 并使用构造注入就这样写
[HttpGet]
public async Task Action_AsyncActionFilter()
{
    Console.WriteLine("Func...");
    await Task.CompletedTask;
}
CustomAsyncActionFilter.cs
using Cnpc.Com.Ioc.IBll;
using Cnpc.Com.Ioc.IDal;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Cnpc.Com.Ioc.WebApp.Filter.ActionFilter
{
    public class CustomAsyncActionFilter : Attribute, IAsyncActionFilter
    {

        ILogger<CustomAsyncActionFilter> logger { get; set; }
        IStudent student { get; set; }
        IWrite write { get;set; }
        public CustomAsyncActionFilter(ILogger<CustomAsyncActionFilter> logger,IStudent student,IWrite write)
        {
            this.logger = logger;
            this.student = student;
            this.write = write;
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            {
                Console.WriteLine("ActionExecutingContext.....");
                logger.LogInformation(context.HttpContext.Request.Path + "before..");
                this.student.DoHomeWork(write);
            }
            ActionExecutedContext executed = await next();
            {
                Console.WriteLine("ActionExecutedContext.....");
                logger.LogInformation(context.HttpContext.Request.Path + "after..");
            }
        }
    }
}

全局注册

Program.cs

//全局注册
builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<CustomAsyncActionFilter>();
});