Перенаправление Из Атрибута Фильтра Действий
каков наилучший способ сделать редирект в ActionFilterAttribute
. У меня есть ActionFilterAttribute
под названием IsAuthenticatedAttributeFilter
и это проверило значение переменной сеанса. Если переменная false, я хочу, чтобы приложение перенаправило на страницу входа в систему. Я бы предпочел перенаправить с помощью имени маршрута SystemLogin
однако любой метод перенаправления в этот момент будет в порядке.
7 ответов:
установить filterContext.Результат
С именем маршруту:
filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues);
вы также можете сделать что-то вроде:
filterContext.Result = new ViewResult { ViewName = SharedViews.SessionLost, ViewData = filterContext.Controller.ViewData };
если вы хотите использовать
RedirectToAction
:вы могли бы сделать публичное
RedirectToAction
метод на вашем контроллере (предпочтительно на своем базовом контроллере) который просто вызывает защищенныйRedirectToAction
СSystem.Web.Mvc.Controller
. Добавление этого метода позволяет сделать публичный вызов кодRedirectToAction
от фильтр.public new RedirectToRouteResult RedirectToAction(string action, string controller) { return base.RedirectToAction(action, controller); }
тогда ваш фильтр будет выглядеть так:
public override void OnActionExecuting(ActionExecutingContext filterContext) { var controller = (SomeControllerBase) filterContext.Controller; filterContext.Result = controller.RedirectToAction("index", "home"); }
в качестве альтернативы перенаправлению, если он вызывает ваш собственный код, вы можете использовать это:
actionContext.Result = new RedirectToRouteResult( new RouteValueDictionary(new { controller = "Home", action = "Error" }) ); actionContext.Result.ExecuteResult(actionContext.Controller.ControllerContext);
Это не чистый редирект, но дает аналогичный результат без лишних накладных расходов.
я использую MVC4, я использовал следующий подход для перенаправления пользовательского экрана html при нарушении авторизации.
расширения
AuthorizeAttribute
сказатьCutomAuthorizer
переопределитеOnAuthorization
иHandleUnauthorizedRequest
зарегистрировать
CustomAuthorizer
наRegisterGlobalFilters
.public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomAuthorizer()); }
по определению
unAuthorized
вызов кHandleUnauthorizedRequest
и перенаправить на соответствующее действие контроллера, как показано ниже.
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" } }); } }
похоже, что вы хотите повторно реализовать или, возможно, расширить,
AuthorizeAttribute
. Если это так, вы должны убедиться, что вы наследуете это, а неActionFilterAttribute
, для того, чтобы позволить ASP.NET в MVC сделать больше работы для вас.кроме того, вы хотите убедиться, что вы разрешаете до вы выполняете любую реальную работу в методе действия-в противном случае единственная разница между входом в систему и не будет той страницей, которую вы видите, когда работа выполнена.
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); } }
есть хороший вопрос С ответ С более подробной информацией здесь на так.
попробовать следующий фрагмент, это должно быть довольно ясно:
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); } }
вы можете наследовать свой контроллер, а затем использовать его внутри фильтра действий
внутри вашего класса ActionFilterAttribute:
if( filterContext.Controller is MyController ) if(filterContext.HttpContext.Session["login"] == null) (filterContext.Controller as MyController).RedirectToAction("Login");
внутри вашего базового контроллера:
public class MyController : Controller { public void RedirectToAction(string actionName) { base.RedirectToAction(actionName); } }
минусы. из этого следует изменить все контроллеры для наследования от класса "MyController"
вот решение, которое также учитывает, если вы используете 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); } } }