Jak przekierować z OnActionExecuting w kontrolerze podstawowym?

184

Próbowałem na dwa sposoby: Response.Redirect (), który nic nie robi, a także wywoływanie nowej metody w kontrolerze podstawowym, która zwraca ActionResult i powoduje, że zwraca RedirectToAction () ... żadna z tych czynności nie działa.

Jak mogę wykonać przekierowanie z metody OnActionExecuting?

MetaGuru
źródło

Odpowiedzi:

362
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }
womp
źródło
79
Zamiast new RedirectResult(url)ciebie możesz również użyć new RedirectToAction(string action, string controller). Mogło to zostać dodane do MVC po opublikowaniu odpowiedzi. Twoje rozwiązanie i tak postawiło mnie na właściwej drodze.
Manfred
3
@Pluc - OnActionExecuting zdarza się jako pierwszy. Jeśli ustawisz kontekst. Wynik, przekierowanie nastąpi przed wykonaniem akcji. (Zweryfikowane przez osobiste testowanie / debugowanie).
James
39
@Manfred Uwaga, przypisanie powinno być wykonane do metody (bez new) RedirectToAction:filterContext.Result = RedirectToAction(string action, string controller);
cederlof
1
@Manfred Chciałem tylko dodać, że nie chciałbyś nowego działania RedirectToAction. To tylko filterContext.Result = RedirectToAction (..)
Sinaesthetic
4
Nazwa „RedirectToAction” nie istnieje w bieżącym kontekście?
Dan Hastings
56

Można to również zrobić w ten sposób:

filterContext.Result = new RedirectToRouteResult(
    new RouteValueDictionary
    {
        {"controller", "Home"},
        {"action", "Index"}
    }
);
Randy Burden
źródło
35

Utwórz osobną klasę,

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

Następnie, gdy tworzysz kontroler, nazwij tę adnotację jako

[RedirectingAction]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
K. Kirivarnan
źródło
Wolę ten anonimowy obiekt dlaRouteValueDictionary konstruktora, ponieważ odzwierciedla on routing w innym miejscu w MVC. +1
Gone Coding
3

Jeśli przekierowany kontroler dziedziczy po tym samym, w baseControllerktórym przesłaniamy OnActionExecutingmetodę, wywołuje pętlę rekurencyjną. Załóżmy, że przekierowujemy go do akcji logowania kontrolera konta, wtedy akcja logowania będzie wywoływać OnActionExecutingmetodę i przekierowywać do tej samej akcji logowania raz za razem ... Więc powinniśmy zastosować OnActionExecutingmetodę odprawy, aby sprawdzić pogodę, czy żądanie pochodzi od tego samego kontrolera, jeśli więc nie przekierowuj go ponownie. oto kod:

chronione zastąpienie.

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 hame
źródło
1
spróbuj {int CompanyId = UserContext.Company.CompanyId; } catch {if (filterContext.Controller.GetType ()! = typeof (AccountController)) {filterContext.Result = nowy RedirectToRouteResult (nowy RouteValueDictionary {{„kontroler”, „Konto”}, {„akcja”, „Logowanie”}} ); }}
abdul hame