205

I have tried two ways: Response.Redirect() which does nothing, as well as calling a new method inside of the Base Controller that returns an ActionResult and have it return RedirectToAction()... neither of these work.

How can I do a redirect from the OnActionExecuting method?

4 Answers 4

386
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }
13
  • 80
    Instead of new RedirectResult(url) you could also use new RedirectToAction(string action, string controller). This may have been added to MVC after you posted your answer. Your solution put me on the right track anyway.
    – Manfred
    Commented Apr 22, 2012 at 2:00
  • 3
    @Pluc - OnActionExecuting happens first. If you set the context.Result, then the redirect happens before the action executes. (Verified by personal testing/debugging.)
    – James
    Commented Apr 22, 2013 at 19:56
  • 42
    @Manfred Note, the assignment should be done to the method (without new) RedirectToAction: filterContext.Result = RedirectToAction(string action, string controller);
    – cederlof
    Commented Jun 3, 2013 at 10:35
  • 1
    @Manfred I just wanted to add that you wouldn't new up the RedirectToAction. It's just filterContext.Result = RedirectToAction(..) Commented Mar 28, 2014 at 15:24
  • 6
    The name 'RedirectToAction' does not exist in the current context?? Commented Apr 29, 2016 at 16:27
62

It can be done this way as well:

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

Create a separate class,

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

Then, When you create a controller, call this annotation as

[RedirectingAction]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
1
  • I prefer this anonymous object for the RouteValueDictionary constructor as it mirrors the routing elsewhere in MVC. +1 Commented Jul 14, 2015 at 11:30
6

If the redirected controller inherit from the same baseController where we override the OnActionExecuting method cause recursive loop. Suppose we redirect it to login action of account controller, then the login action will call OnActionExecuting method and redirected to the same login action again and again

... So we should apply a check in OnActionExecuting method to check weather the request is from the same controller if so then do not redirect it login action again. here is the code:

protected override 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
  • 1
    try { int CompanyId = UserContext.Company.CompanyId; } catch { if (filterContext.Controller.GetType() != typeof(AccountController)) { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "controller", "Account" }, { "action", "Login" } }); } } Commented Jul 1, 2016 at 6:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.