Redirect From Action Filter Attribut
Quelle est la meilleure façon de faire une redirection dans un ActionFilterAttribute
. J'ai un ActionFilterAttribute
appelé IsAuthenticatedAttributeFilter
et qui a vérifié la valeur d'une variable de session. Si la variable est false, je veux que l'application redirige vers la page de connexion. Je préférerais rediriger en utilisant le nom de route SystemLogin
cependant n'importe quelle méthode de redirection à ce point serait très bien.
7 réponses
Set filterContext.Résultat
avec le nom de route:
filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues);
vous pouvez aussi faire quelque chose comme:
filterContext.Result = new ViewResult
{
ViewName = SharedViews.SessionLost,
ViewData = filterContext.Controller.ViewData
};
si vous voulez utiliser RedirectToAction
:
vous pouvez faire un public RedirectToAction
méthode sur votre contrôleur ( de préférence sur son contrôleur de base ) qui appelle simplement le protégé RedirectToAction
de System.Web.Mvc.Controller
. L'ajout de cette méthode permet un appel public à votre RedirectToAction
à partir du filtre.
public new RedirectToRouteResult RedirectToAction(string action, string controller)
{
return base.RedirectToAction(action, controller);
}
alors votre filtre ressemblerait à quelque chose comme:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = (SomeControllerBase) filterContext.Controller;
filterContext.Result = controller.RedirectToAction("index", "home");
}
alternativement à une redirection, si elle appelle votre propre code, vous pouvez utiliser ceci:
actionContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { controller = "Home", action = "Error" })
);
actionContext.Result.ExecuteResult(actionContext.Controller.ControllerContext);
ce n'est pas une pure redirection mais donne un résultat similaire sans frais généraux inutiles.
j'utilise MVC4, j'ai utilisé l'approche suivante pour rediriger un écran html personnalisé en cas de violation d'autorisation.
Étendre AuthorizeAttribute
dire CutomAuthorizer
remplacer le OnAuthorization
et HandleUnauthorizedRequest
enregistre le CustomAuthorizer
dans le RegisterGlobalFilters
.
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomAuthorizer());
}
après avoir identifié le unAuthorized
"appel d'accès HandleUnauthorizedRequest
et redirigé vers le contrôleur concerné comme indiqué ci-dessous.
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" }
});
}
}
on dirait que vous voulez ré-implémenter, ou éventuellement étendre, AuthorizeAttribute
. Si c'est le cas, vous devez vous assurer que vous héritez de cette, et non ActionFilterAttribute
, afin de laisser ASP.NET MVC fait plus de travail pour vous.
aussi, vous voulez vous assurer que vous autorisez avant vous faites n'importe quel travail réel dans la méthode d'action - autrement, la seule différence entre connecté et pas sera Ce page que vous voyez quand le travail est fait.
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);
}
}
Il y a un bon question avec un réponse avec plus de détails ici sur.
Essayez l'extrait suivant, il devrait être assez clair:
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);
}
}
vous pouvez hériter de votre contrôleur puis l'utiliser à l'intérieur de votre filtre d'action
dans votre classe ActionFilterAttribute:
if( filterContext.Controller is MyController )
if(filterContext.HttpContext.Session["login"] == null)
(filterContext.Controller as MyController).RedirectToAction("Login");
dans votre contrôleur de base:
public class MyController : Controller
{
public void RedirectToAction(string actionName) {
base.RedirectToAction(actionName);
}
}
Cons. de ceci est de changer tous les contrôleurs pour hériter de "MyController" classe
Voici une solution qui prend également en compte si vous utilisez des requêtes 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);
}
}
}