.Net Core ActionFilter

发布时间 2023-08-05 17:05:09作者: 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

Demo

CustomAsyncActionFilter.cs

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.....");
            }
        }
    }
}

TestFilterController.cs

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;
        }
    }
}

如何在Actionfilter使用日志

Action.cs

//[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>();
});