Wie kann ich den Filter dazu bringen, zu einer anderen Aktion umzuleiten?

77

RedirectToActionist geschützt und wir können es nur innerhalb von Aktionen verwenden. Aber wenn ich in einen Filter umleiten möchte?

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

Antworten:

104

RedirectToActionist nur eine Hilfsmethode, um eine zu RedirectToRouteResult()erstellen. Sie erstellen also einfach eine neue RedirectToRouteResult()Übergabe RouteValueDictionary()mit Werten für Ihre Aktion.

Vollständiges Beispiel basierend auf Code von @Domenic im Kommentar unten:

public class IsGuestAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Ctx.User.IsGuest) 
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary 
                { 
                    { "controller", "Home" }, 
                    { "action", "Index" } 
                });
        }
    }
}
vegetarisch
quelle
1
Sie können diesen Code auch in die OnExceptionMethode einfügen , solange Sie festlegenfilterContext.ExceptionHandled = true;
Demoncodemonkey
88

Hier ist ein Codebeispiel:

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);
    }
}
StuperUser
quelle
16
Oder einfachnew RedirectToRouteResult(new RouteValueDictionary { { "controller", "Home" }, {"action", "HomePage" } })
Domenic
13
Wenn Sie diesen Kommentar nur mit einem grünen Resharper unterstrichen hätten
CRice
1
Sie können diesen Code auch in die OnExceptionMethode einfügen , solange Sie festlegenfilterContext.ExceptionHandled = true;
Demoncodemonkey
1

Ich weiß, dass ich ein bisschen zu spät zur Party komme, aber ich habe Veggerbys Lösung verwendet und eine Hilfsklasse erstellt, die für manche Leute nützlich sein kann. Deshalb wollte ich sie hier bereitstellen:

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

Ich habe sowohl eine statische Methode bereitgestellt, die eine Umleitung zurückgibt, als auch ActionResulteine Erweiterungsmethode, die erweitert wird filterContext. Hoffe, jemand findet das nützlich.

ObjectDictionaryist eine Klasse, die mithilfe der Reflexion ein Wörterbuch aus den Eigenschaften des Objekts erstellt, aus dem es erstellt wurde. Ich habe diesen Code nicht eingefügt, weil ich glaube, dass es irgendwo im Framework einen besseren Weg gibt, dies zu tun. Ich habe es noch nicht gefunden, aber ich möchte nicht, dass andere meine potenziellen Fehler erben.

Jordanien
quelle
0

Sicherheits- / Autorisierungs- / Authentifizierungsfilter sollten AuthorizeAttribute und IAuthorizationFilter verwenden .

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" } 
                });
        }
    }
}
Erik Philips
quelle
0

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

Hier ist eine Hilfsklasse, die ich mit einigen Erweiterungsmethoden geschrieben habe, die geschrieben wurden, um an mehreren Stellen RedirectToAction-Funktionen bereitzustellen. Dies ist viel zu spät für das OP, aber hoffentlich hilft es jemandem!

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

Es gibt mehr ControllerContexts, die nicht enthalten sind, aber es sollte ziemlich einfach sein, Ihre eigenen basierend auf Ihren Anforderungen hinzuzufügen.

Austin Hummel
quelle