2009-02-15 25 views
71

RedirectToAction está protegido, y podemos usarlo solo dentro de las acciones. Pero si quiero redirigir en un filtro?¿Cómo hacer para que el filtro redirija a otra acción?

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

Respuesta

92

RedirectToAction es sólo un método de ayuda para construir un RedirectToRouteResult(), así que lo que hace es simplemente crear una nueva RedirectToRouteResult() pasando a lo largo de un RouteValueDictionary() con los valores de su acción.

muestra completa basada en el código de @Domenic en el comentario a continuación:

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

También puede poner este código en el método 'OnException', siempre que configure' filterContext.ExceptionHandled = true; ' – demoncodemonkey

87

Aquí está un ejemplo de código:

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

O simplemente' new RedirectToRouteResult (new RouteValueDictionary {{"controller", "Home"}, { "acción", "Página de inicio"}}) ' – Domenic

+13

Si solo pudieras haber dicho ese comentario con un resharper verde subrayado – CRice

+1

También puedes poner este código en el método' OnException', siempre y cuando configures 'filterContext.ExceptionHandled = true ; ' – demoncodemonkey

0

de seguridad/autorización/autenticación Los filtros deben utilizar el AuthorizeAttribute y 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

Yo sé que soy un poco tarde a la fiesta, pero he usado la solución de Veggerby y construyó una clase de ayuda que puede ser útil para algunas personas, por lo que quería ofrecer aquí:

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

Proporcioné un método estático que devuelve un redireccionamiento ActionResult y un método de extensión que se extiende a filterContext. Espero que alguien encuentre esto útil.

ObjectDictionary es una clase que usa la reflexión para crear un diccionario a partir de las propiedades del objeto desde el que está construido. No incluí ese código porque creo que hay una manera mejor de hacerlo en algún lugar del marco. Aún no lo he encontrado, pero no quiero que otros hereden mis posibles errores.

0

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

Aquí es una clase de ayuda que escribí con algunos métodos de extensión escritos para proporcionar funcionalidad RedirectToAction en más lugares. Esto es demasiado tarde para el OP, pero espero que ayude a alguien.

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

Hay más ControllerContexts que no están incluidos, pero debería ser bastante fácil agregar el suyo según sus necesidades.

Cuestiones relacionadas