¿Cómo redirigir desde OnActionExecuting en Base Controller?

185

He intentado de dos maneras: Response.Redirect () que no hace nada, además de llamar a un nuevo método dentro del controlador base que devuelve un ActionResult y hace que devuelva RedirectToAction () ... ninguno de estos funciona.

¿Cómo puedo hacer una redirección desde el método OnActionExecuting?

CloudMeta
fuente

Respuestas:

363
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }
womp
fuente
79
En lugar de new RedirectResult(url)usted también podría usar new RedirectToAction(string action, string controller). Es posible que esto se haya agregado a MVC después de publicar su respuesta. Su solución me puso en el camino correcto de todos modos.
Manfred
3
@Pluc: OnActionExecuting ocurre primero. Si establece el contexto. Resultado, la redirección se produce antes de que se ejecute la acción. (Verificado por pruebas personales / depuración.)
James
39
@Manfred Nota, la asignación debe hacerse al método (sin new) RedirectToAction:filterContext.Result = RedirectToAction(string action, string controller);
cederlof
1
@Manfred Solo quería agregar que no renovarías el RedirectToAction. Es solo filterContext.Result = RedirectToAction (..)
Sinaesthetic
44
El nombre 'RedirectToAction' no existe en el contexto actual ??
Dan Hastings
56

También se puede hacer de esta manera:

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

Crea una clase separada,

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

Luego, cuando cree un controlador, llame a esta anotación como

[RedirectingAction]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
K.Kirivarnan
fuente
Prefiero este objeto anónimo para elRouteValueDictionary constructor, ya que refleja el enrutamiento en otro lugar en MVC. +1
Codificación desaparecida
3

Si el controlador redirigido hereda del mismo baseControllerdonde anulamos el OnActionExecutingmétodo, causaremos un bucle recursivo. Supongamos que lo redirigimos a la acción de inicio de sesión del controlador de cuenta, luego la acción de inicio de sesión llamará al OnActionExecutingmétodo y se redirigirá a la misma acción de inicio de sesión una y otra vez ... Por lo tanto, debemos aplicar un OnActionExecutingmétodo de registro para verificar si la solicitud es del mismo controlador si entonces no redirija la acción de inicio de sesión nuevamente. Aquí está el código:

anulación protegida.

void OnActionExecuting(ActionExecutingContext filterContext)
{
   try
   {
      some condition ...
   }
   catch
   {
      if (filterContext.Controller.GetType() !=     typeof(AccountController))
      {
         filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Account" }, { "action", "Login" } });
      }
   }
}
abdul hameed
fuente
1
pruebe {int CompanyId = UserContext.Company.CompanyId; } catch {if (filterContext.Controller.GetType ()! = typeof (AccountController)) {filterContext.Result = new RedirectToRouteResult (new RouteValueDictionary {{"controller", "Account"}, {"action", "Login"}} ); }}
abdul hameed