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

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

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

Global.asax,在 Application_Start() 中:

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

过滤器A:

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

过滤器B:

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

我一定是遗漏了什么...我已经尝试在设置结果前后运行 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");
        }
    }
}

我已经为两个过滤器添加了一些逻辑(您可能想要重构它)以确保当前 Controller 不是 Foo Controller ,或者如果当前 Controller 是 Foo那么操作可能不同于 BarBaz .

这应该可以防止循环,其中过滤器 FilterA重定向到 ~/Foo/Bar ,然后新请求被 FilterB 拦截重定向到 ~/Foo/Baz这将被 FilterA 再次拦截等等。

例如,如果您使用这些过滤器创建一个新的 MVC5 应用程序,如果您转到 ~/ ,您将被重定向到 ~/Foo/Bar通过 FilterA .但是,如果您转到 ~/Account/Login ,您将被重定向到 ~/Foo/Baz通过 FilterB .

希望对您有所帮助!

关于c# - ASP.NET MVC ActionFilter 不会阻止其他过滤器运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22773305/

相关文章:

c# - Aforge 和 Windows 窗体的内存堆叠问题

C# 如何更改 Outlook 中的发件人字段

c# - asp.net mvc 3 handleerror 全局过滤器总是显示 IIS 状态 500 页

c# - 我如何在 ASP.NET MVC 5 中抽象出这种重复模式?

jquery - 使用AngularJS双击获取li的子div id

c# - 使用 IAppBuilder.UseWebApi 时出现问题

c# - 是否可以在批处理文件中发出等待命令?

c# - 我的代码中出现"Specified element is already the logical child of another element. Disconnect it first"错误,有什么解决办法吗?

c# - 明确指定模型数据类型 MVC/C#

jquery - 文件生成的 throbber