206

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

389
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }
Sign up to request clarification or add additional context in comments.

13 Comments

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.
@Pluc - OnActionExecuting happens first. If you set the context.Result, then the redirect happens before the action executes. (Verified by personal testing/debugging.)
@Manfred Note, the assignment should be done to the method (without new) RedirectToAction: filterContext.Result = RedirectToAction(string action, string controller);
@Manfred I just wanted to add that you wouldn't new up the RedirectToAction. It's just filterContext.Result = RedirectToAction(..)
The name 'RedirectToAction' does not exist in the current context??
|
62

It can be done this way as well:

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

Comments

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 Comment

I prefer this anonymous object for the RouteValueDictionary constructor as it mirrors the routing elsewhere in MVC. +1
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 Comment

try { int CompanyId = UserContext.Company.CompanyId; } catch { if (filterContext.Controller.GetType() != typeof(AccountController)) { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "controller", "Account" }, { "action", "Login" } }); } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.