[英]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
那么动作可能与Bar
和Baz
不同。
这应该防止过滤器FilterA
重定向到~/Foo/Bar
的循环,然后新请求被FilterB
拦截,重定向到~/Foo/Baz
,它将被FilterA
再次拦截,依此类推。
举个例子,如果你创建这些过滤器新MVC5应用程序,如果你去到~/
,你将被重定向到~/Foo/Bar
由FilterA
。 但是如果你去~/Account/Login
,你会被FilterB
重定向到~/Foo/Baz
。
希望能帮助到你!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.