Apa cara terbaik untuk melakukan pengalihan di file ActionFilterAttribute
. Saya telah sebuah ActionFilterAttribute
disebut IsAuthenticatedAttributeFilter
dan yang memeriksa nilai variabel sesi. Jika variabelnya salah, saya ingin aplikasi dialihkan ke halaman login. Saya lebih suka mengalihkan menggunakan nama rute SystemLogin
namun metode pengalihan apa pun pada saat ini akan baik-baik saja.
c#
asp.net-mvc
asp.net-mvc-3
redirect
routes
ryanzec.dll
sumber
sumber
Jawaban:
Setel filterContext.Result
Dengan nama rute:
filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues);
Anda juga dapat melakukan sesuatu seperti:
filterContext.Result = new ViewResult { ViewName = SharedViews.SessionLost, ViewData = filterContext.Controller.ViewData };
Jika Anda ingin menggunakan
RedirectToAction
:Anda dapat membuat
RedirectToAction
metode publik pada pengontrol Anda ( sebaiknya pada pengontrol dasarnya ) yang hanya memanggil dilindungiRedirectToAction
dariSystem.Web.Mvc.Controller
. Menambahkan metode ini memungkinkan panggilan publik ke AndaRedirectToAction
dari filter.public new RedirectToRouteResult RedirectToAction(string action, string controller) { return base.RedirectToAction(action, controller); }
Maka filter Anda akan terlihat seperti ini:
public override void OnActionExecuting(ActionExecutingContext filterContext) { var controller = (SomeControllerBase) filterContext.Controller; filterContext.Result = controller.RedirectToAction("index", "home"); }
sumber
protected
jadi Anda tidak akan memiliki akses ke sana dari filter.protected
harus ada penjelasan yang masuk akal? Saya merasa sangat kotor mendefinisikan kembali aksesibilitas iniRedirectToAction
tanpa memahami mengapa itu dikemas di tempat pertama.Alternatifnya untuk pengalihan, jika memanggil kode Anda sendiri, Anda dapat menggunakan ini:
actionContext.Result = new RedirectToRouteResult( new RouteValueDictionary(new { controller = "Home", action = "Error" }) ); actionContext.Result.ExecuteResult(actionContext.Controller.ControllerContext);
Ini bukan pengalihan murni tetapi memberikan hasil serupa tanpa biaya tambahan yang tidak perlu.
sumber
actionContext.Result.ExecuteResult
dari dalam filter tindakan Anda - MVC akan melakukannya secara otomatis setelah filter tindakan berjalan (asalkanactionContext.Result
tidak null).Saya menggunakan MVC4, saya menggunakan pendekatan berikut untuk mengarahkan ulang layar html kustom setelah pelanggaran otorisasi.
Perpanjang
AuthorizeAttribute
katakanCutomAuthorizer
timpaOnAuthorization
danHandleUnauthorizedRequest
Daftarkan
CustomAuthorizer
diRegisterGlobalFilters
.public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomAuthorizer()); }
setelah mengidentifikasi
unAuthorized
panggilan aksesHandleUnauthorizedRequest
dan mengalihkan ke tindakan pengontrol terkait seperti yang ditunjukkan di bawah ini.public class CustomAuthorizer : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { bool isAuthorized = IsAuthorized(filterContext); // check authorization base.OnAuthorization(filterContext); if (!isAuthorized && !filterContext.ActionDescriptor.ActionName.Equals("Unauthorized", StringComparison.InvariantCultureIgnoreCase) && !filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.Equals("LogOn", StringComparison.InvariantCultureIgnoreCase)) { HandleUnauthorizedRequest(filterContext); } } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary{{ "controller", "LogOn" }, { "action", "Unauthorized" } }); } }
sumber
Sepertinya Anda ingin menerapkan ulang, atau mungkin memperpanjang
AuthorizeAttribute
,. Jika demikian, Anda harus memastikan bahwa Anda mewarisinya, dan tidakActionFilterAttribute
, agar ASP.NET MVC melakukan lebih banyak pekerjaan untuk Anda.Selain itu, Anda ingin memastikan bahwa Anda memberi otorisasi sebelum Anda melakukan pekerjaan nyata apa pun dalam metode tindakan - jika tidak, satu-satunya perbedaan antara masuk dan tidak adalah halaman apa yang Anda lihat saat pekerjaan selesai.
public class CustomAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { // Do whatever checking you need here // If you want the base check as well (against users/roles) call base.OnAuthorization(filterContext); } }
Ada pertanyaan bagus dengan jawaban dengan detail lebih lanjut di SO.
sumber
Coba cuplikan berikut, seharusnya cukup jelas:
public class AuthorizeActionFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(FilterExecutingContext filterContext) { HttpSessionStateBase session = filterContext.HttpContext.Session; Controller controller = filterContext.Controller as Controller; if (controller != null) { if (session["Login"] == null) { filterContext.Cancel = true; controller.HttpContext.Response.Redirect("./Login"); } } base.OnActionExecuting(filterContext); } }
sumber
Berikut adalah solusi yang juga memperhitungkan jika Anda menggunakan permintaan Ajax.
using System; using System.Web.Mvc; using System.Web.Routing; namespace YourNamespace{ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class AuthorizeCustom : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { if (YourAuthorizationCheckGoesHere) { string area = "";// leave empty if not using area's string controller = "ControllerName"; string action = "ActionName"; var urlHelper = new UrlHelper(context.RequestContext); if (context.HttpContext.Request.IsAjaxRequest()){ // Check if Ajax if(area == string.Empty) context.HttpContext.Response.Write($"<script>window.location.reload('{urlHelper.Content(System.IO.Path.Combine(controller, action))}');</script>"); else context.HttpContext.Response.Write($"<script>window.location.reload('{urlHelper.Content(System.IO.Path.Combine(area, controller, action))}');</script>"); } else // Non Ajax Request context.Result = new RedirectToRouteResult(new RouteValueDictionary( new{ area, controller, action })); } base.OnActionExecuting(context); } } }
sumber
Ini berfungsi untuk saya (asp.net core 2.1)
using JustRide.Web.Controllers; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; namespace MyProject.Web.Filters { public class IsAuthenticatedAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { if (context.HttpContext.User.Identity.IsAuthenticated) context.Result = new RedirectToActionResult(nameof(AccountController.Index), "Account", null); } } } [AllowAnonymous, IsAuthenticated] public IActionResult Index() { return View(); }
sumber
Anda dapat mewarisi pengontrol Anda kemudian menggunakannya di dalam filter tindakan Anda
di dalam kelas ActionFilterAttribute Anda:
if( filterContext.Controller is MyController ) if(filterContext.HttpContext.Session["login"] == null) (filterContext.Controller as MyController).RedirectToAction("Login");
di dalam pengontrol dasar Anda:
public class MyController : Controller { public void RedirectToAction(string actionName) { base.RedirectToAction(actionName); } }
Kontra. ini untuk mengubah semua pengontrol untuk mewarisi dari kelas "MyController"
sumber