如何在ASP.NET MVC 2中的每个控制器操作之前获取某些代码?

Chr*_*ris 37 asp.net-mvc

我想检查一些关于会话状态,用户代理等的事情,并且可能采取行动并在控制器方法有机会执行之前返回特殊视图.例如:

最常见的:
用户请求Home/Index
System检查以确保x!= 0.
x不等于零,因此Home/Index控制器执行正常.

但是,有时候:
用户请求Home/Index
System检查以确保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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当myValue出错时,这些用户将获得Notice视图,并且永远不会执行所请求的控制器.为了完成这项工作,我将它应用于我所有控制器继承的ControllerBase.

Ros*_*ied 45

一切都取决于你想要做什么,以及如何做.以下三个选项:


您可以为此使用路径约束.在评估要匹配的路径时执行它们.

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"}
);
Run Code Online (Sandbox Code Playgroud)

上面的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
           }
      }


}
Run Code Online (Sandbox Code Playgroud)

另一个选择是让所有控制器(或相关控制器)继承自您制作的自定义控制器,并覆盖:

OnActionExecuting
Run Code Online (Sandbox Code Playgroud)

详情请见此处.

与过滤器或路由约束相同.