web-dev-qa-db-fra.com

Comment faire pour que le filtre redirige vers une autre action?

RedirectToAction est protégé et nous ne pouvons l'utiliser que dans des actions. Mais si je veux rediriger dans un filtre?

public class IsGuestAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Ctx.User.IsGuest) 
            filterContext.Result = (filterContext.Controller as Controller)
                .RedirectToAction("Index", "Home");
    }
}
74
appqui-platform

RedirectToAction est simplement une méthode d'assistance pour construire une RedirectToRouteResult(). Vous créez donc simplement une nouvelle RedirectToRouteResult() en transmettant une RouteValueDictionary() avec des valeurs pour votre action.

Échantillon complet basé sur le code de @Domenic dans le commentaire ci-dessous:

public class IsGuestAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Ctx.User.IsGuest) 
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary 
                { 
                    { "controller", "Home" }, 
                    { "action", "Index" } 
                });
        }
    }
}
99
veggerby

Voici un exemple de code:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{

    if (!Ctx.User.IsGuest)
    {
        RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary();
        redirectTargetDictionary.Add("action", "Index");
        redirectTargetDictionary.Add("controller", "Home");

        filterContext.Result = new RedirectToRouteResult(redirectTargetDictionary);
    }
}
88
StuperUser

Je sais que je suis un peu en retard pour la fête, mais j'ai utilisé la solution de veggerby et construit une classe d'aide qui peut être utile à certaines personnes.

public static class ActionFilterHelpers
{
    public static void Redirect(this ActionExecutingContext filterContext, String controller, String action, object routeValues)
    {
        filterContext.Result = Redirect(controller, action, routeValues);
    }

    public static ActionResult Redirect(String controller, String action, object routeValues)
    {
        var routeValues = new RouteValueDictionary();

        routeValues["controller"] = controller;
        routeValues["action"] = action;

        foreach (var keyValue in new ObjectDictionary(routeValues))
            routeValues.Add(keyValue.Key, keyValue.Value);

        return new RedirectToRouteResult(routeValues);
    }
}

J'ai fourni à la fois une méthode statique qui retourne une redirection ActionResult et une méthode d'extension qui étend filterContext. J'espère que quelqu'un trouve cela utile.

ObjectDictionary est une classe qui utilise la réflexion pour créer un dictionnaire à partir des propriétés de l'objet à partir duquel il est construit. Je n'ai pas inclus ce code parce que je crois qu'il existe une meilleure façon de le faire quelque part dans le cadre. Je ne l'ai pas encore trouvé, mais je ne veux pas que les autres héritent de mes bugs potentiels.

1
Jordan

Les filtres de sécurité/autorisation/authentification doivent utiliser AuthorizeAttribute et IAuthorizationFilter .

public class IsGuestAttribute: AuthorizeAttribute, IAuthorizationFilter
{
    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
    }
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Ctx.User.IsGuest) 
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary 
                { 
                    { "controller", "Home" }, 
                    { "action", "Index" } 
                });
        }
    }
}
0
Erik Philips

Utilisation: filterContext.RedirectToAction("Login", "Account");

Voici une classe d'assistance que j'ai écrite avec certaines méthodes d'extension écrites pour fournir la fonctionnalité RedirectToAction à plusieurs endroits. C'est beaucoup trop tard pour le PO mais j'espère que cela aidera quelqu'un!

public static class RedirectHelper
{
    // RedirectToAction Extension Methods
    public static void RedirectToAction(this HttpResponseBase response, String action, String controller, object routeValues = null, bool endResponse = false)
    {
        response.RedirectToRoute(CreateRoute(action, controller, routeValues));
        if (endResponse) response.End();
    }
    public static void RedirectToAction(this HttpResponse response, String action, String controller, object routeValues = null, bool endResponse = false)
    {
        response.RedirectToRoute(CreateRoute(action, controller, routeValues));
        if (endResponse) response.End();
    }
    public static void RedirectToAction(this ActionExecutingContext filterContext, String action, String controller, object routeValues = null, bool endResponse = false)
    {
        if (endResponse) filterContext.HttpContext.Response.RedirectToAction(action, controller, routeValues, true);
        else filterContext.Result = new RedirectToRouteResult(CreateRoute(action, controller, routeValues));
    }
    public static void RedirectToAction(this ExceptionContext filterContext, String action, String controller, object routeValues = null, bool endResponse = false)
    {
        if (endResponse) filterContext.HttpContext.Response.RedirectToAction(action, controller, routeValues, true);
        else {
            filterContext.ExceptionHandled = true;
            filterContext.Result = new RedirectToRouteResult(CreateRoute(action, controller, routeValues));
        }
    }
    // Route Value Derivation
    public static RouteValueDictionary CreateRoute(String action, String controller, object routeValues = null)
    {
        RouteValueDictionary result = routeValues != null ? 
            HtmlHelper.AnonymousObjectToHtmlAttributes(routeValues) : 
            new RouteValueDictionary();
        result["controller"] = controller;
        result["action"] = action;
        return result;
    }
}

Il y a plus de ControllerContexts qui ne sont pas inclus mais il devrait être assez facile d'ajouter les vôtres selon vos besoins.

0
Austin Hummel