asp.net core MVC 过滤器会在请求管道的各个阶段触发。同一阶段又可以注册多个范围的过滤器,例如Global范围,controller范围等。以ActionFilter为例,我们来看看过滤器的触发顺序。
过滤器可注册范围
- 全局:将作用于所有请求的action
- controller:将作用于这个controller下的所有action
- action:作用于单个action
定义过滤器
全局
public class GlobalActionFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var factory = context.HttpContext.RequestServices.GetService<ILoggerFactory>(); var logger = factory.CreateLogger<GlobalActionFilter>(); logger.LogWarning("全局ActionFilter执行之前"); await next(); logger.LogWarning("全局ActionFilter执行之后"); } }
controller(分为注解方式和重写方式)
注解方式:
public class ControllerActionFilter : ActionFilterAttribute { public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var factory = context.HttpContext.RequestServices.GetService<ILoggerFactory>(); var logger = factory.CreateLogger<GlobalActionFilter>(); logger.LogWarning("ControllerActionFilter执行之前"); await next(); logger.LogWarning("ControllerActionFilter执行之后"); } }
重写方式(在controller内重写OnActionExecutionAsync)
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var logger = _factory.CreateLogger<ValuesController>(); logger.LogWarning("Controller内部重写的actionFinter执行前"); await next(); logger.LogWarning("Controller内部重写的actionFinter执行后"); }
应用过滤器
全局(在Startup中修改)
public void ConfigureServices(IServiceCollection services) { services.AddMvc(o => { o.Filters.Add<GlobalActionFilter>(); }); }
controller(重写方式直接可用不用操作)
[ControllerActionFilter] public class ValuesController : Controller
Action
[HttpGet] [ActionActionFilter] public IEnumerable<string> Get()
执行结果
从结果可以看出,Controller重写 > 全局 > Controller > Action
自定义过滤器执行顺序
过滤器的执行顺序不是一成不变的,aspNet Core 通过灵活的设计让我们可以手动自定义过滤器的执行顺序。要实现自定义过滤器执行顺序则需要实现IOrderedFilter接口,该接口定义一个int类型的Order属性,这个属性越大则执行顺序越滞后。
实现IOrderFilter接口
public class GlobalActionFilter : IAsyncActionFilter,IOrderedFilter { public int Order => 0;
继承Attribute方式直接传入参数
[ControllerActionFilter(Order =-1)] public class ValuesController : Controller {
[HttpGet] [ActionActionFilter(Order =-2)] public IEnumerable<string> Get() {
结果
此时的执行顺序:controller内部重写 > Action > controller > global
时间: 2024-10-20 21:40:02