Bagaimana cara mengarahkan dari OnActionExecuting di Base Controller?

185

Saya telah mencoba dua cara: Response.Redirect () yang tidak melakukan apa-apa, serta memanggil metode baru di dalam Pengontrol Dasar yang mengembalikan ActionResult dan mengembalikannya RedirectToAction () ... tidak satu pun dari pekerjaan ini.

Bagaimana saya bisa melakukan redirect dari metode OnActionExecuting?

CloudMeta
sumber

Jawaban:

363
 public override void OnActionExecuting(ActionExecutingContext filterContext)
 {
    ...
    if (needToRedirect)
    {
       ...
       filterContext.Result = new RedirectResult(url);
       return;
    }
    ...
 }
womp
sumber
79
Alih-alih new RedirectResult(url)Anda juga bisa menggunakan new RedirectToAction(string action, string controller). Ini mungkin telah ditambahkan ke MVC setelah Anda memposting jawaban Anda. Solusi Anda menempatkan saya di jalur yang benar.
Manfred
3
@ Plluc - OnActionExecuting terjadi lebih dulu. Jika Anda mengatur konteks.Hasil, maka pengalihan terjadi sebelum tindakan dijalankan. (Diverifikasi oleh pengujian pribadi / debugging.)
James
39
@Manfred Note, penugasan harus dilakukan dengan metode (tanpa new) RedirectToAction:filterContext.Result = RedirectToAction(string action, string controller);
cederlof
1
@ Manfred Saya hanya ingin menambahkan bahwa Anda tidak akan baru memperbarui RedirectToAction. Itu hanya filterContext.Result = RedirectToAction (..)
Sinaesthetic
4
Nama 'RedirectToAction' tidak ada dalam konteks saat ini ??
Dan Hastings
56

Ini dapat dilakukan dengan cara ini juga:

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

Buat kelas yang terpisah,

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

Kemudian, Saat Anda membuat pengontrol, panggil anotasi ini sebagai

[RedirectingAction]
public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}
K.Kirivarnan
sumber
Saya lebih suka objek anonimRouteValueDictionary ini untuk konstruktor karena mencerminkan perutean di tempat lain di MVC. +1
Lewat Pengodean
3

Jika pengalihan diarahkan mewarisi dari tempat yang sama di baseControllermana kita menimpa OnActionExecutingmetode menyebabkan loop rekursif. Misalkan kita mengarahkannya ke tindakan masuk dari pengontrol akun, maka tindakan masuk akan memanggil OnActionExecutingmetode dan dialihkan ke tindakan masuk yang sama lagi dan lagi ... Jadi kita harus menerapkan metode check in OnActionExecutinguntuk memeriksa cuaca permintaan dari pengontrol yang sama jika jadi jangan mengarahkan kembali tindakan login itu. ini kodenya:

override yang dilindungi.

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