Como redirecionar do OnActionExecuting no Controlador Base?

185

Eu tentei de duas maneiras: Response.Redirect () que não faz nada, além de chamar um novo método dentro do Controlador Base que retorna um ActionResult e retorna RedirectToAction () ... nenhum desses trabalhos.

Como posso redirecionar a partir do método OnActionExecuting?

CloudMeta
fonte

Respostas:

363
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }
womp
fonte
79
Em vez de new RedirectResult(url)você também pode usar new RedirectToAction(string action, string controller). Isso pode ter sido adicionado ao MVC depois que você postou sua resposta. Sua solução me colocou no caminho certo de qualquer maneira.
Manfred
3
@Pluc - OnActionExecuting acontece primeiro. Se você definir o context.Result, o redirecionamento ocorrerá antes da execução da ação. (Verificado por teste pessoal / depuração.) #
James James
39
Nota @Manfred, a atribuição deve ser feito para o método (sem newRedirectToAction):filterContext.Result = RedirectToAction(string action, string controller);
cederlof
1
@Manfred Eu só queria acrescentar que você não iria usar o RedirectToAction. É apenas filterContext.Result = RedirectToAction (..)
Sinaesthetic
4
O nome 'RedirectToAction' não existe no contexto atual ??
Dan Hastings
56

Também pode ser feito desta maneira:

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

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

Então, quando você cria um controlador, chame esta anotação como

[RedirectingAction]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
K.Kirivarnan
fonte
Eu prefiro esse objeto anônimo para oRouteValueDictionary construtor, pois ele reflete o roteamento em outro lugar no MVC. +1
Gone Coding
3

Se o controlador redirecionado herdar do mesmo baseControllerem que substituímos o OnActionExecutingmétodo, causamos loop recursivo. Suponha que o redirecionemos para a ação de login do controlador de conta, a ação de login chamará o OnActionExecutingmétodo e será redirecionada para a mesma ação de login repetidamente ... Portanto, devemos aplicar um OnActionExecutingmétodo de check-in para verificar se a solicitação é do mesmo controlador se portanto, não redirecione novamente a ação de login. aqui está o código:

substituição 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
fonte
1
tente {int CompanyId = UserContext.Company.CompanyId; } catch {if (filterContext.Controller.GetType ()! = typeof (AccountController)) {filterContext.Result = new RedirectToRouteResult (new RouteValueDictionary {{"controller", "Account"}, {"action", "Login"}} ); }}
Abdul Hameed