gpt4 book ai didi

c# - 在ASP.NET Core中在 Controller OnActionExecuting之前执行全局过滤器

转载 作者:行者123 更新时间:2023-12-03 22:34:15 26 4
gpt4 key购买 nike

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

// ...
}

现在 FooActionFilterControllerActionFilter具有相同的顺序。但是 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com