我到处都读到将 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
那么操作可能不同于 Bar
和 Baz
.
这应该可以防止循环,其中过滤器 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/