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.

113
demandé sur Syakur Rahman 2011-03-28 03:53:33

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");
}
158
répondu CRice 2017-04-02 15:40:48

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.

67
répondu Syakur Rahman 2015-07-23 02:44:47

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

                                         });

    }
}
11
répondu user2834076 2016-06-28 03:10:12

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.

9
répondu Tomas Aschan 2017-05-23 12:02:51

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);
  }
}
4
répondu msoliman 2013-08-12 07:14:58

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

1
répondu msoliman 2013-05-07 11:05:02

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);
        }
    }
}
1
répondu Mike 2018-03-13 14:05:28