我想检查一些关于会话的状态,用户代理等的状态,并且可能采取行动并在控制器方法获得执行机会之前返回一个特殊的视图。例如:
最常见的:
用户请求Home / Index
系统检查以确保x!= 0。
x不等于零,因此Home / Index控制器执行正常。
但是有时:
用户请求Home / Index
系统检查以确保x!= 0。
x DOES等于零。必须通知用户,并且不能允许请求的控制器操作执行。
我认为这涉及使用ActionFilters。但我已经阅读了他们,我不明白,如果我可以抢占控制器方法和返回一个视图之前,它执行。我相信我可以在控制器方法运行之前执行代码,但我如何保持它在一些实例运行并返回自定义视图,或直接到不同的控制器方法?
更新:我实现了RM的解决方案。这是我做的:
public class MyAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (myValue == wrongValue) { filterContext.Result = new ViewResult{ViewName = "Notice"}; } base.OnActionExecuting(filterContext); } }
现在,当myValue错误时,这些用户获得通知视图,并且所请求的控制器从不执行。为了完成这项工作,我把它应用到我所有的控制器继承的ControllerBase。
解决方法
所有取决于你想要做什么,以及如何。以下三个选项:
您可以为此使用路由约束。它们在评估匹配的路由时执行。
routes.MapRoute( "HomeWithConstraint","Home/{action}",new {controller="Home",action="index"},new { x = new MyCustomRouteConstraint () } ); // without constraint,i.e. if above didnt pass routes.MapRoute( "HomeWithConstraint",action="index"} );
上面的MyCustomRouteConstraint类型将检查您的示例中的x == 0等。不确定您想要做什么,但这将允许您在运行之前检查条件并设置其他路由值等。
或者,您可以使用自定义ActionFilter,只需将其应用于控制器类,并且在执行任何操作之前将被调用。就像是:
public class CheckXActionFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if(x == 0) { // do something // e.g. Set ActionParameters etc } else { // do something else } } }
另一个选项是让所有的控制器(或相关的)继承自定制的控制器,并覆盖:
OnActionExecuting
详见here。
要做与过滤器相同的,或路由约束。