【问题标题】:What is the Filter Scope for and why the weird names?过滤器范围是什么以及为什么奇怪的名字?
【发布时间】:2015-08-17 11:56:18
【问题描述】:

根据这个documentation for ASP.NET Filters过滤器按以下顺序运行:

  1. 授权过滤器
  2. 动作过滤器
  3. 响应过滤器
  4. 异常过滤器

在每个过滤器类型中都有一个过滤器Order指定运行顺序。

到目前为止是有道理的......但后来它变得很奇怪。

在每个过滤器类型和顺序中还有另一种排序方法,它表示为以下值的枚举:

public enum FilterScope
{
    First = 0,
    Global = 10,
    Controller = 20,
    Action = 30,
    Last = 100,
}

全局、控制器和动作在动作过滤器的运行顺序中的作用是什么?

例如:

如果我有两个动作过滤器,它们的运行顺序分别为 1 和控制器和动作的 FilterScope

ControllerAction 除了在另一个之前订购,还有什么作用?

更离奇的事

According to this FilterScope 为过滤器提供第三级排序。 ControllerGlobalAction 如何成为一个过滤器的命令,它绝不限于仅用于 ControllerAction 并且不一定适用于全局?它不是对订单的描述。

另外,如果它确实提供了第三级过滤,为什么它仅限于 5 个选项?

【问题讨论】:

  • 我认为FilterScope 定义了您使用过滤器的位置:全局、整个控制器或某些操作。所以第一个将执行的将是一个全局过滤器,然后是控制器,然后是动作
  • 对您有帮助吗:msdn.microsoft.com/en-us/library/… ?
  • @VsevolodGoloviznin 我也这么认为,但这并不能解释为什么要为每个filter type and order 指定它,它肯定会超越这些。所以它将是:过滤器范围、过滤器类型、过滤器顺序。不是反过来吗?
  • @Serv 遗憾的是,该页面仅包含与我在问题中发布的文档相同的信息:(
  • FilterScope 似乎只是用于在多个过滤器中使用时设置过滤器的顺序,但对我来说这就是 Order 的用途。为什么我要将过滤器设置为Order = 0(第一)和FilterScope = Last。这没有任何意义。它不限制过滤器的使用,it just sets the ordering

标签: c# asp.net-mvc action-filter


【解决方案1】:

Filter 对象,实际具有Scope 属性的对象,是根据使用情况构造的——当您将过滤器添加到全局应用程序过滤器时,Filter 对象是用@ 的Scope 构造的987654327@。同样,当从控制器和操作收集过滤器属性时,Filter 对象将分别使用ControllerAction 的范围构造。

我不完全确定 FilterScopeFirstLast 的实际创建方式。

指定这些规则是为了说明如果您在全局级别和操作级别使用相同的 Order 值声明了过滤器,将如何应用平局 - 这比过滤器更值得关注在您需要手动确保每个过滤器使用唯一的Order 的同一级别声明(如果您关心排序)。

【讨论】:

  • 我认为默认是First,因为它是enum中的第一个,这导致它与0相等
【解决方案2】:

嗯,我真的不明白你到底发现了什么奇怪的地方。

Authorization、Action、Response 和 Exception 过滤器是您可以实现以运行过滤器逻辑的 4 个接口,分别为 IAuthorizationFilterIActionFilterIResultFilterIExceptionFilter 接口。

之后,业务规则就出来了。例如,您必须检查某些用户操作的访问权限。您不仅实现了授权过滤器,还创建了用于检查规则的逻辑,例如:

  • 如果用户没有完成注册,你必须提醒他。无论用户在您的网站上做什么,此规则都应在 First 运行。
  • 如果用户没有被批准,他不能查看站点内容,并且应该得到一个验证消息。所以它是一个Global 范围的规则,它应该在任何其他用户权限检查之前运行。
  • 如果用户无权访问某个部门,则他无法查看站点上有关该部门的某些内容,但不是全部 - 所以我们让Controller 选择应该向用户显示的内容。
  • 如果用户不是管理员,他不能编辑或删除某些内容。所以,这是一个具体的Action,正在被过滤。
  • 我们可以在任务处理完毕后启动一些记录器,所以我们必须等到工作完成,然后在Last 运行过滤器。

我在这里看到了一个非常简单的过滤器排序模型,我可以为每一对提供一个样本或filter type/filter scope

更新:

some sample code for a Filter's ordering:

public class ControllerInstanceFilterProvider : IFilterProvider {
    public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
        if (controllerContext.Controller != null) {
            // Use FilterScope.First and Order of Int32.MinValue to ensure controller instance methods always run first
            yield return new Filter(controllerContext.Controller, FilterScope.First, Int32.MinValue);
        }
    }
}

【讨论】:

  • 感谢您的回答。根据文档,过滤器范围是三级排序,而不是设置它的应用位置
  • 我也找不到设置 FilterScope 的单个示例,你可以吗?
  • @Coulton 是的,我已经说过这只是关于ordering,应该用于复杂的过滤器层次结构。
  • @Coulton 只找到一个,MSDN 上没有。我认为这是一个过度工程,但在极少数情况下仍然可以使用
【解决方案3】:

据我了解

过滤器顺序,这意味着过滤器运行的顺序。所以过滤器按以下顺序运行:

  1. 授权过滤器
  2. 动作过滤器
  3. 响应过滤器
  4. 异常过滤器

在每个过滤器类型中,Order 值指定运行顺序。 在每个过滤器类型和顺序中,SCOPE 枚举值指定过滤器的顺序。

例如: Order 属性设置为零且过滤范围设置为 first 的 OnActionExecuting() 过滤器在具有 order 属性的操作过滤器之前运行设置为零并将过滤范围设置为 Action

顺序和范围用于在每个过滤器类型之间进行内部优先级排序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 2023-01-12
    • 2021-10-21
    • 2018-11-11
    相关资源
    最近更新 更多