2009-02-15 11 views
71

RedirectToAction è protetto e possiamo utilizzarlo solo all'interno delle azioni. Ma se voglio reindirizzare in un filtro?Come ottenere il filtro per reindirizzare a un'altra azione?

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

risposta

92

RedirectToAction è solo un metodo di supporto per costruire un RedirectToRouteResult(), in modo da ciò che si fa è semplicemente creare un nuovo RedirectToRouteResult() passando lungo un RouteValueDictionary() con i valori per la vostra azione.

campione completo basato sul codice da @Domenic nel commento qui sotto:

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

È anche possibile inserire questo codice nel metodo 'OnException', a condizione che si imposti' filterContext.ExceptionHandled = true; ' – demoncodemonkey

87

Ecco un esempio di codice:

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

Oppure solo' new RedirectToRouteResult (nuovo RouteValueDictionary {{"controller", "Home"}, { "action", "HomePage"}}) ' – Domenic

+13

Se solo avessi potuto dire che il commento con sottolineatore verde sottolineatura – CRice

+1

Puoi anche inserire questo codice nel metodo' OnException', a patto di impostare 'filterContext.ExceptionHandled = true ; ' – demoncodemonkey

0

sicurezza/autorizzazione Filtri/autenticazione dovrebbe utilizzare il AuthorizeAttribute e 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" } 
       }); 
     } 
    } 
} 
1

So che sono un po 'in ritardo alla festa, ma ho usato la soluzione di veggerby e costruito una classe di supporto che può essere utile per alcune persone, così ho voluto fornire qui:

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

Ho fornito sia un metodo statico che restituisce un reindirizzamento ActionResult e un metodo di estensione che estende filterContext. Spero che qualcuno lo ritenga utile.

ObjectDictionary è una classe che utilizza la riflessione per creare un dizionario dalle proprietà dell'oggetto da cui è stato costruito. Non ho incluso quel codice perché credo che ci sia un modo migliore per farlo da qualche parte nel framework. Non l'ho ancora trovato, ma non voglio che gli altri ereditino i miei potenziali bug.

0

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

Ecco una classe di supporto che ho scritto con alcuni metodi di estensione scritti per fornire funzionalità RedirectToAction in più luoghi. Questo è troppo tardi per l'OP, ma si spera che aiuti qualcuno!

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

Non ci sono più ControllerContexts che non sono inclusi ma dovrebbe essere abbastanza facile da aggiungere la tua base alle vostre esigenze.

Problemi correlati