在ASP.NET Core 2.0应用程序中,我尝试在执行Controller的变体之前执行全局过滤器OnActionExecuting
。预期的行为是我可以在全局之前准备一些东西并将结果值传递给控制器。然而,当前的行为是执行的顺序被设计逆转。
文档告诉我有关default order of execution:
的信息从Controller基类继承的每个控制器都包含OnActionExecuting和OnActionExecuted方法。这些方法包装为给定操作运行的过滤器:在任何过滤器之前调用OnActionExecuting,并在所有过滤器之后调用OnActionExecuted。
这导致我解释控制器OnActionExecuting
在任何过滤器之前执行。说得通。但文档还通过实施IOrderedFilter
来说明the default order can be overridden。
我尝试在过滤器中实现它是这样的:
public class FooActionFilter : IActionFilter, IOrderedFilter
{
// Setting the order to 0, using IOrderedFilter, to attempt executing
// this filter *before* the BaseController's OnActionExecuting.
public int Order => 0;
public void OnActionExecuting(ActionExecutingContext context)
{
// removed logic for brevity
var foo = "bar";
// Pass the extracted value back to the controller
context.RouteData.Values.Add("foo", foo);
}
}
此过滤器在启动时注册为:
services.AddMvc(options => options.Filters.Add(new FooActionFilter()));
最后,我的BaseController看起来像下面的示例。这最好地解释了我想要实现的目标:
public class BaseController : Controller
{
public override void OnActionExecuting(ActionExecutingContext context)
{
// The problem: this gets executed *before* the global filter.
// I actually want the FooActionFilter to prepare this value for me.
var foo = context.RouteData.Values.GetValueOrDefault("foo").ToString();
}
}
将Order
设置为0,或者甚至将非零值设置为-1,似乎对执行顺序没有任何影响。
我的问题:如何让我的全局过滤器执行OnActionExecuting
之前(基本)控制器OnActionExecuting
?
答案 0 :(得分:3)
你快到了。您的小错误是控制器过滤器执行的默认顺序不是0
。此订单在ControllerActionFilter
类中定义为int.MinValue
(source code):
public class ControllerActionFilter : IAsyncActionFilter, IOrderedFilter
{
// Controller-filter methods run farthest from the action by default.
/// <inheritdoc />
public int Order { get; set; } = int.MinValue;
// ...
}
因此,您应对当前代码进行的唯一更改是将FooActionFilter.Order
设置为int.MinValue
:
public class FooActionFilter : IActionFilter, IOrderedFilter
{
public int Order => int.MinValue;
// ...
}
现在FooActionFilter
和ControllerActionFilter
的订单相同。但FooActionFilter
是全局过滤器,而ControllerActionFilter
是控制器级过滤器。这就是基于this statement:
FooActionFilter
将首先执行的原因
在确定过滤器的运行顺序时,Order属性胜过范围。过滤器首先按顺序排序,然后范围用于打破关系。