Comment rediriger depuis OnActionExecuting dans Base Controller?

185

J'ai essayé deux façons: Response.Redirect () qui ne fait rien, ainsi que l'appel d'une nouvelle méthode à l'intérieur du contrôleur de base qui renvoie un ActionResult et le fait renvoyer RedirectToAction () ... aucun de ces deux ne fonctionne.

Comment puis-je faire une redirection à partir de la méthode OnActionExecuting?

CloudMeta
la source

Réponses:

363
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }
womp
la source
79
Au lieu de cela, new RedirectResult(url)vous pouvez également utiliser new RedirectToAction(string action, string controller). Cela peut avoir été ajouté à MVC après avoir publié votre réponse. Votre solution m'a quand même mis sur la bonne voie.
Manfred
3
@Pluc - OnActionExecuting se produit en premier. Si vous définissez le paramètre context.Result, la redirection se produit avant l'exécution de l'action. (Vérifié par des tests / débogages personnels.)
James
39
@Manfred Remarque, l'affectation doit être faite à la méthode (sans new) RedirectToAction:filterContext.Result = RedirectToAction(string action, string controller);
cederlof
1
@Manfred Je voulais juste ajouter que vous ne feriez pas de nouveau la RedirectToAction. C'est juste filterContext.Result = RedirectToAction (..)
Sinaesthetic
4
Le nom 'RedirectToAction' n'existe pas dans le contexte actuel ??
Dan Hastings
56

Cela peut également être fait de cette façon:

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

Créez une classe séparée,

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

Ensuite, lorsque vous créez un contrôleur, appelez cette annotation comme

[RedirectingAction]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
K.Kirivarnan
la source
Je préfère cet objet anonyme pour leRouteValueDictionary constructeur car il reflète le routage ailleurs dans MVC. +1
Fini le codage du
3

Si le contrôleur redirigé hérite de celui baseControlleroù nous remplaçons la OnActionExecutingméthode, cela provoque une boucle récursive. Supposons que nous le redirigeons vers l'action de connexion du contrôleur de compte, puis l'action de connexion appellera la OnActionExecutingméthode et sera redirigée vers la même action de connexion encore et encore ... Nous devrions donc appliquer une vérificationOnActionExecuting méthode d'enregistrement pour vérifier si la demande provient du même contrôleur si alors ne redirigez pas l'action de connexion à nouveau. voici le code:

remplacement protégé.

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
la source
1
essayez {int CompanyId = UserContext.Company.CompanyId; } catch {if (filterContext.Controller.GetType ()! = typeof (AccountController)) {filterContext.Result = new RedirectToRouteResult (new RouteValueDictionary {{"controller", "Account"}, {"action", "Login"}} ); }}
abdul hameed