如何有选择地禁用ASP.Net MVC中的全局过滤器

zsz*_*zep 72 asp.net-mvc actionfilterattribute global-filter

我为我的所有控制器操作设置了一个全局过滤器,我在其中打开和关闭NHibernate会话.这些操作中有95%需要一些数据库访问,但有5%没有.是否有任何简单的方法来禁用这5%的全局过滤器.我可以反过来只装饰需要数据库的动作,但这将是更多的工作.

Dar*_*rov 139

你可以写一个标记属性:

public class SkipMyGlobalActionFilterAttribute : Attribute
{
}
Run Code Online (Sandbox Code Playgroud)

然后在您的全局操作过滤器测试中,该操作上是否存在此标记:

public class MyGlobalActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(SkipMyGlobalActionFilterAttribute), false).Any())
        {
            return;
        }

        // here do whatever you were intending to do
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,如果要从全局过滤器中排除某些操作,只需使用marker属性进行装饰:

[SkipMyGlobalActionFilter]
public ActionResult Index()
{
    return View();
}
Run Code Online (Sandbox Code Playgroud)

  • 这非常有用,谢谢.只是为了帮助未来的人,你也可以在Controller上放置相同的东西,并使用filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes来应用于所有操作. (4认同)
  • 任何人在api解决方案之后的语法略有不同:actionContext.ActionDescriptor.GetCustomAttributes <SkipMyGlobalActionFilter>().Any() (4认同)
  • 就像Leniel写的那样,在ASP.NET Core中,filterContext.ActionDescriptor并没有GetCustomAttributes方法.如何在ASP.NET核心中执行此操作? (2认同)

Len*_*rri 19

你也可以做这篇精彩帖子中描述的内容:

排除过滤器

只需实现自定义ExcludeFilterAttribute,然后实现自定义ExcludeFilterProvider.

清洁解决方案,对我来说很棒!


Dr.*_*MAF 8

虽然,由达林季米特洛夫接受的答案是罚款和工作良好,但对我来说,创立了最简单,最有效的答案在这里.

您只需要在属性中添加一个布尔属性,并在逻辑开始之前检查它:

public class DataAccessAttribute: ActionFilterAttribute
{
    public bool Disable { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (Disable) return;

        // Your original logic for your 95% actions goes here.
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的5%行动中,就像这样使用它:

[DataAccessAttribute(Disable=true)]
public ActionResult Index()
{            
    return View();
}
Run Code Online (Sandbox Code Playgroud)


g t*_*g t 8

在 AspNetCore 中,@darin-dimitrov 接受的答案可以调整为如下工作:

首先,IFilterMetadata在标记属性上实现:

public class SkipMyGlobalActionFilterAttribute : Attribute, IFilterMetadata
{
}
Run Code Online (Sandbox Code Playgroud)

然后在Filters该属性上搜索该属性ActionExecutingContext

public class MyGlobalActionFilter : IActionFilter
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (context.Filters.OfType<SkipMyGlobalActionFilterAttribute>().Any())
        {
            return;
        }

        // etc
    }
}
Run Code Online (Sandbox Code Playgroud)