在ASP.NET Core 2.0应用程序中,我试图在执行Controller的变体之前执行全局过滤器的OnActionExecuting
。预期的行为是,我可以在全局之前准备一些东西,然后将结果值传递给 Controller 。但是,当前的行为是执行顺序被设计颠倒了。
该文档告诉我有关default order of execution的信息:
Every controller that inherits from the Controller base class includes OnActionExecuting and OnActionExecuted methods. These methods wrap the filters that run for a given action: OnActionExecuting is called before any of the filters, and OnActionExecuted is called after all of the filters.
这使我解释说, Controller 的
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),似乎都不会对执行顺序产生任何影响。我的问题:我该怎么做才能使全局过滤器在(Base)Controller的
OnActionExecuting
之前执行OnActionExecuting
?
最佳答案
你快到了。您的小错误是 Controller 过滤器执行的默认顺序不是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
是 Controller 级过滤器。这就是为什么基于this statement首先执行FooActionFilter
的原因:The Order property trumps scope when determining the order in which filters will run. Filters are sorted first by order, then scope is used to break ties.
关于c# - 在ASP.NET Core中在 Controller OnActionExecuting之前执行全局过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49908073/