2009-02-15 46 views
71

RedirectToAction受保護,我們只能在行動中使用它。但是如果我想在過濾器中重定向?如何讓過濾器重定向到另一個動作?

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

回答

92

RedirectToAction只是一種輔助方法來構造一個RedirectToRouteResult(),所以你做的是簡單地創建一個新的RedirectToRouteResult()沿RouteValueDictionary()傳遞與值你的行動。在下面的評論基於從@Domenic代碼

完整的示例:

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

只要設置了`filterContext.ExceptionHandled = true;` – demoncodemonkey 2015-06-03 20:47:10

87

下面是一個代碼示例:

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

或者只是`new RedirectToRouteResult(new RouteValueDictionary {{「controller」,「Home」},{ 「action」,「HomePage」}})` – Domenic 2010-10-15 16:39:39

0

安全/授權/認證過濾器應使用AuthorizeAttributeIAuthorizationFilter

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

我知道我有點遲到了,但我用veggerby的解決方案,並建立了一個輔助類,可能是對某些人有用的,所以我想在這裏它提供:

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

我提供了一個返回重定向的靜態方法ActionResult和一個擴展方法,它擴展了filterContext。希望有人認爲這有用。

ObjectDictionary是一個使用反射從構造它的對象的屬性創建字典的類。我沒有包含那些代碼,因爲我相信在框架的某個地方有更好的方法來做。我還沒有找到它,但我不希望別人繼承我的潛在錯誤。

0

用法:filterContext.RedirectToAction("Login", "Account");

這裏是一個輔助類,我寫在更多的地方提供RedirectToAction一些功能擴展方法寫的。對於OP來說這太晚了,但希望它可以幫助別人!

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

還有更多ControllerContexts沒有包括在內,但根據您的需求添加您自己的控件應該很容易。

相關問題