I want to check some things about the state of the session, the user agent, etc, and possibly take action and return a special view BEFORE a controller method gets a chance to execute. For example:
我想检查一些关于会话状态、用户代理等的事情,并且可能在控制器方法得到执行之前,采取行动并返回一个特殊的视图。例如:
Most common:
User requests Home/Index
System checks to make sure x != 0.
x does not equal zero, so the Home/Index controller executes like normal.
最常见的:用户请求Home/Index系统检查以确保x != 0。x不等于0,所以Home/Index控制器像往常一样执行。
But, sometimes:
User requests Home/Index
System checks to make sure x != 0.
x DOES equal zero. The user must be notified and the requested controller action cannot be allowed to execute.
但是,有时:用户请求Home/Index系统检查以确保x != 0。x = 0。必须通知用户并不能执行所请求的控制器操作。
I think this involves the use of ActionFilters. But I have read about them and I don't understand if I can preempt the controller method and return a view before it executes. I am sure I could execute code before the controller method runs, but how do I keep it from running in some instances and return a custom view, or direct to a different controller method?
我认为这涉及到使用actionfilter。但是我已经读过它们,我不知道是否可以抢占controller方法并在它执行之前返回一个视图。我确信我可以在controller方法运行之前执行代码,但是我如何防止它在某些实例中运行并返回自定义视图,或者直接返回到另一个控制器方法?
Update: I implemented RM's solution. This is what I did:
更新:我实现了RM的解决方案。这就是我所做的:
public class MyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (myValue == wrongValue)
{
filterContext.Result = new ViewResult{ViewName = "Notice"};
}
base.OnActionExecuting(filterContext);
}
}
Now, when myValue is wrong, those users get the Notice view and the requested controller is never executed. To make this work I applied it to a ControllerBase that all my Controllers inherit from.
现在,当myValue出错时,这些用户会得到通知视图,并且请求的控制器不会被执行。为了完成这项工作,我将它应用到我所有的控制器都继承的控制器基础上。
2 个解决方案
#1
41
All depends what exactly you want to do, and how. Three options below:
这一切都取决于你到底想做什么,以及如何去做。下面三个选项:
You can use route constraints for this. They are executed when evaluating the route to match to.
您可以为此使用路由约束。在评估匹配的路由时执行。
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",
"Home/{action}",
new {controller="Home", action="index"}
);
The MyCustomRouteConstraint type above would check for x==0 etc in your example. Not sure exactly what you want to do, but this will allow you to check conditions before running and set additional route values etc.
上面的MyCustomRouteConstraint类型将在示例中检查x==0等等。不确定您想要做什么,但是这将允许您在运行之前检查条件并设置额外的路由值等。
See here for example of custom route constraints.
请参见这里的自定义路由约束示例。
Alternativly, yes you can use a custom ActionFilter, just apply it to the controller class, and it will be called before any action is executed. Something like:
另外,您可以使用定制的ActionFilter,将它应用到controller类中,在执行任何操作之前调用它。喜欢的东西:
public class CheckXActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if(x == 0)
{
// do something
// e.g. Set ActionParameters etc
}
else
{
// do something else
}
}
}
Another option is to have all you controllers (or the relevant ones) inherit from a custom controller you make, and override :
另一种方法是让所有的控制器(或相关的控制器)继承自定义的控制器,并覆盖:
OnActionExecuting
See here for details.
有关详细信息,请参阅这里。
To do the same as the filter, or routing constraints.
执行与筛选器或路由约束相同的操作。
#2
0
One way you can do this is to redirect to a different ActionMethod to show the view. Code example is in this discussion:
一种方法是重定向到另一个ActionMethod来显示视图。代码示例在本讨论中:
Redirecting to specified controller and action in asp.net mvc action filter
重定向到asp.net mvc操作过滤器中指定的控制器和操作
#1
41
All depends what exactly you want to do, and how. Three options below:
这一切都取决于你到底想做什么,以及如何去做。下面三个选项:
You can use route constraints for this. They are executed when evaluating the route to match to.
您可以为此使用路由约束。在评估匹配的路由时执行。
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",
"Home/{action}",
new {controller="Home", action="index"}
);
The MyCustomRouteConstraint type above would check for x==0 etc in your example. Not sure exactly what you want to do, but this will allow you to check conditions before running and set additional route values etc.
上面的MyCustomRouteConstraint类型将在示例中检查x==0等等。不确定您想要做什么,但是这将允许您在运行之前检查条件并设置额外的路由值等。
See here for example of custom route constraints.
请参见这里的自定义路由约束示例。
Alternativly, yes you can use a custom ActionFilter, just apply it to the controller class, and it will be called before any action is executed. Something like:
另外,您可以使用定制的ActionFilter,将它应用到controller类中,在执行任何操作之前调用它。喜欢的东西:
public class CheckXActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if(x == 0)
{
// do something
// e.g. Set ActionParameters etc
}
else
{
// do something else
}
}
}
Another option is to have all you controllers (or the relevant ones) inherit from a custom controller you make, and override :
另一种方法是让所有的控制器(或相关的控制器)继承自定义的控制器,并覆盖:
OnActionExecuting
See here for details.
有关详细信息,请参阅这里。
To do the same as the filter, or routing constraints.
执行与筛选器或路由约束相同的操作。
#2
0
One way you can do this is to redirect to a different ActionMethod to show the view. Code example is in this discussion:
一种方法是重定向到另一个ActionMethod来显示视图。代码示例在本讨论中:
Redirecting to specified controller and action in asp.net mvc action filter
重定向到asp.net mvc操作过滤器中指定的控制器和操作