Как перенаправить из OnActionExecuting в Base Controller?

185

Я попробовал два способа: Response.Redirect (), который ничего не делает, а также вызов нового метода внутри базового контроллера, который возвращает ActionResult и возвращает RedirectToAction () ... ни одна из этих работ.

Как я могу сделать перенаправление из метода OnActionExecuting?

CloudMeta
источник

Ответы:

363
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }
WOMP
источник
79
Вместо new RedirectResult(url)вас также можно использовать new RedirectToAction(string action, string controller). Возможно, это было добавлено в MVC после того, как вы опубликовали свой ответ. Ваше решение в любом случае поставило меня на правильный путь.
Манфред
3
@Pluc - OnActionExecuting происходит первым. Если вы установите context.Result, то перенаправление произойдет до того, как действие будет выполнено. (Проверено личным тестированием / отладкой.)
Джеймс
39
@Manfred Обратите внимание, что назначение должно быть сделано для метода (без new) RedirectToAction:filterContext.Result = RedirectToAction(string action, string controller);
cederlof
1
@Manfred Я просто хотел добавить, что вы не будете создавать RedirectToAction. Это всего лишь filterContext.Result = RedirectToAction (..)
Sinaesthetic
4
Имя RedirectToAction не существует в текущем контексте.
Дэн Гастингс,
56

Это можно сделать и так:

filterContext.Result = new RedirectToRouteResult(
    new RouteValueDictionary
    {
        {"controller", "Home"},
        {"action", "Index"}
    }
);
Рэнди Бёрден
источник
35

Создать отдельный класс,

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

Затем, когда вы создаете контроллер, вызывайте эту аннотацию как

[RedirectingAction]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
K.Kirivarnan
источник
Я предпочитаю этот анонимный объект дляRouteValueDictionary конструктора, поскольку он отражает маршрутизацию в другом месте в MVC. +1
ушел кодирование
3

Если перенаправленный контроллер наследуется от того же места, baseControllerгде мы переопределяем OnActionExecutingметод, вызовем рекурсивный цикл. Предположим, мы перенаправили его на действие входа контроллера учетной записи, затем действие входа вызовет OnActionExecutingметод и снова и снова будет перенаправлен на одно и то же действие входа в систему ... Поэтому мы должны применить OnActionExecutingметод check in, чтобы проверить, поступил ли запрос от того же контроллера, если так что тогда не перенаправляйте это действие входа снова. вот код:

защищенное переопределение.

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
try {int CompanyId = UserContext.Company.CompanyId; } catch {if (filterContext.Controller.GetType ()! = typeof (AccountController)) {filterContext.Result = new RedirectToRouteResult (new RouteValueDictionary {{"controller", "Account"}, {"action", "Login"}} ); }}
Абдул Хамид