繁体   English   中英

ASP.NET MVC ActionFilter不会阻止其他过滤器运行

[英]ASP.NET MVC ActionFilter is not preventing other filters from running

我在任何地方都读到了设置context.Result到一个非null值会阻止同一个类中的其他过滤器运行,但它对我来说不起作用。 以下结果导致两个过滤器之间的重定向循环:

Application_Start() Global.asax:

GlobalFilters.Filters.Add(new FilterA(), 1);
GlobalFilters.Filters.Add(new FilterB(), 2);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

FilterA:

public class FilterA : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (long thing that evaluates to true)
        {
            context.Result = new RedirectResult("~/Foo/Bar");
        }
    }
}

FilterB:

public class FilterB : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (...also true, but shouldn't run...)
        {
            context.Result = new RedirectResult("~/Foo/Baz");
        }
    }
}

我必须遗漏一些东西......我已经尝试在设置Result之前和之后运行base.OnActionExecuting(context) ,但似乎并不重要。

这导致重定向循环可能是因为过滤器中的逻辑不排除对"Foo/Bar""Foo/Baz"请求。 基本上在FilterA上设置结果是阻止其他过滤器在该请求中运行并返回重定向,但FilterB在重定向后的下一个请求上执行。

以下适用于新的MVC5应用程序:

public class FilterA : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.RouteData.GetRequiredString("controller").Equals("account", StringComparison.CurrentCultureIgnoreCase) //long condition evaluating to true
            //logic controlling these filters dont apply to Foo/Bar and Foo/Baz
            && (!context.RouteData.GetRequiredString("controller").Equals("Foo", StringComparison.CurrentCultureIgnoreCase)
                || (!context.RouteData.GetRequiredString("action").Equals("Bar", StringComparison.CurrentCultureIgnoreCase)
                    && !context.RouteData.GetRequiredString("action").Equals("Baz", StringComparison.CurrentCultureIgnoreCase))
                )
            )
        {
            context.Result = new RedirectResult("~/Foo/Bar");
        }
    }
}

public class FilterB : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (true /*long condition evaluating to true*/
            //logic controlling these filters dont apply to Foo/Bar and Foo/Baz
            && (!context.RouteData.GetRequiredString("controller").Equals("Foo", StringComparison.CurrentCultureIgnoreCase)
                || (!context.RouteData.GetRequiredString("action").Equals("Bar", StringComparison.CurrentCultureIgnoreCase)
                    && !context.RouteData.GetRequiredString("action").Equals("Baz", StringComparison.CurrentCultureIgnoreCase))
                )
            )
        {
            context.Result = new RedirectResult("~/Foo/Baz");
        }
    }
}

我已经向两个过滤器添加了一些逻辑(你可能想要重构它),以确保当前控制器不是Foo控制器,或者如果当前控制器是Foo那么动作可能与BarBaz不同。

这应该防止过滤器FilterA重定向到~/Foo/Bar的循环,然后新请求被FilterB拦截,重定向到~/Foo/Baz ,它将被FilterA再次拦截,依此类推。

举个例子,如果你创建这些过滤器新MVC5应用程序,如果你去到~/ ,你将被重定向到~/Foo/BarFilterA 但是如果你去~/Account/Login ,你会被FilterB重定向到~/Foo/Baz

希望能帮助到你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM