如何从Base Controller中的OnActionExecuting重定向?


184

我尝试了两种方法:什么都不做的Response.Redirect(),以及在基本控制器内部调用一个返回ActionResult并使其返回RedirectToAction()的新方法……这两种方法都不起作用。

如何从OnActionExecuting方法进行重定向?

Answers:


362
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }

79
代替new RedirectResult(url)您也可以使用new RedirectToAction(string action, string controller)。发布您的答案后,这可能已添加到MVC。无论如何,您的解决方案使我走上了正确的轨道。
Manfred 2012年

3
@Pluc-OnActionExecuting首先发生。如果设置context.Result,则重定向将在操作执行之前发生。(通过个人测试/调试验证。)
James

39
@Manfred注意,应该对方法进行分配(不带new)RedirectToAction:filterContext.Result = RedirectToAction(string action, string controller);
cederlof 2013年

1
@Manfred我只是想补充一点,您不会重新创建RedirectToAction。这只是filterContext.Result = RedirectToAction(..)
Sinaesthetic 2014年

4
名称“ RedirectToAction”在当前上下文中不存在?
Dan Hastings

56

也可以通过这种方式完成:

filterContext.Result = new RedirectToRouteResult(
    new RouteValueDictionary
    {
        {"controller", "Home"},
        {"action", "Index"}
    }
);

35

创建一个单独的类,

    public class RedirectingAction : ActionFilterAttribute
    {
      public override void OnActionExecuting(ActionExecutingContext context)
      {
        base.OnActionExecuting(context);

        if (CheckUrCondition)
        {
            context.Result = new RedirectToRouteResult(new RouteValueDictionary(new
            {
                controller = "Home",
                action = "Index"
            }));
        }
      }
   }

然后,在创建控制器时,将该注释称为

[RedirectingAction]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

我更喜欢此匿名对象作为RouteValueDictionary构造函数,因为它可以镜像MVC中其他地方的路由。+1
编码已于2015年

3

如果重定向的控制器继承自baseController我们重写该OnActionExecuting方法的位置,则将导致递归循环。假设我们将其重定向到帐户控制器的登录操作,然后登录操作将调用OnActionExecuting方法并一次又一次重定向到相同的登录操作...因此,如果存在以下情况,我们应该应用签入OnActionExecuting方法来检查请求是否来自同一控制器:因此,请勿再次重定向登录操作。这是代码:

受保护的覆盖。

void OnActionExecuting(ActionExecutingContext filterContext)
{
   try
   {
      some condition ...
   }
   catch
   {
      if (filterContext.Controller.GetType() !=     typeof(AccountController))
      {
         filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Account" }, { "action", "Login" } });
      }
   }
}

1
尝试{int CompanyId = UserContext.Company.CompanyId; } { ); }
阿卜杜勒·哈默
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.