代码之家  ›  专栏  ›  技术社区  ›  Christopher

如何在ASP.NET MVC 2中的每个控制器操作之前执行特定的代码?

  •  36
  • Christopher  · 技术社区  · 14 年前

    我想检查一些关于会话状态、用户代理等的信息,并可能在控制器方法获得执行机会之前采取操作并返回一个特殊视图。例如:

    最常见的:
    用户请求主页/索引
    系统检查以确保X!= 0。
    x不等于零,因此主/索引控制器的执行方式与正常情况相同。

    但是,有时:
    用户请求主页/索引
    系统检查以确保X!= 0。
    X等于零。必须通知用户,并且不能执行请求的控制器操作。

    认为 这涉及到操作过滤器的使用。但是我已经读过它们了,我不明白我是否可以在控制器方法执行之前抢先返回一个视图。我确信我可以在控制器方法运行之前执行代码,但是如何防止它在某些实例中运行并返回自定义视图,或者直接指向其他控制器方法?

    更新:我实现了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。

    2 回复  |  直到 12 年前
        1
  •  42
  •   bogert    12 年前

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


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

    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"}
    );
    

    上面的myCustomRouteConstraint类型将在示例中检查x==0等。不确定您要做什么,但这将允许您在运行前检查条件并设置其他路由值等。

    here 例如自定义路由约束。


    或者,是的,您可以使用一个自定义的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 详情。

    执行与过滤器或路由约束相同的操作。

        2
  •  0
  •   Community Paul Sweatte    7 年前

    可以这样做的一种方法是重定向到另一个actionMethod以显示视图。代码示例在本讨论中:

    Redirecting to specified controller and action in asp.net mvc action filter