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