2009-02-15 22 views
71

RedirectToAction được bảo vệ và chúng tôi chỉ có thể sử dụng nó bên trong các hành động. Nhưng nếu tôi muốn chuyển hướng trong một bộ lọc?Cách nhận bộ lọc để chuyển hướng đến một hành động khác?

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

Trả lời

92

RedirectToAction chỉ là một phương pháp helper để xây dựng một RedirectToRouteResult(), vì vậy những gì bạn làm chỉ đơn giản là tạo ra một mới RedirectToRouteResult() đi dọc theo một RouteValueDictionary() với các giá trị cho hành động của bạn.

mẫu Toàn bộ dựa trên mã từ @Domenic trong bình luận dưới đây:

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

Bạn cũng có thể đặt mã này trong phương thức 'OnException', miễn là bạn đặt' filterContext.ExceptionHandled = true; ' – demoncodemonkey

87

Dưới đây là một ví dụ mã:

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

Hoặc chỉ' new RedirectToRouteResult (new RouteValueDictionary {{"controller", "Home"}, { "action", "HomePage"}}) ' – Domenic

+13

Nếu chỉ có bạn mới có thể nói rằng lời nhận xét với đường gạch dưới màu xanh lá cây gạch chân – CRice

+1

Bạn cũng có thể đặt mã này vào phương thức' OnException', miễn là bạn đặt 'filterContext.ExceptionHandled = true ; ' – demoncodemonkey

0

Security/Authorization Filters/Xác thực nên sử dụng 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

Tôi biết rằng tôi là một chút muộn để đảng, nhưng tôi sử dụng giải pháp veggerby và xây dựng một lớp helper có thể hữu ích cho một số người, vì vậy tôi muốn cung cấp cho nó ở đây:

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

Tôi đã cung cấp cả phương thức tĩnh trả về chuyển hướng ActionResult và phương pháp mở rộng kéo dài filterContext. Hy vọng ai đó thấy điều này hữu ích.

ObjectDictionary là lớp sử dụng sự phản chiếu để tạo từ điển từ các thuộc tính của đối tượng mà từ đó nó được tạo. Tôi không bao gồm mã đó bởi vì tôi tin rằng có một cách tốt hơn để làm điều đó ở đâu đó trong khuôn khổ. Tôi chưa tìm thấy nó, nhưng tôi không muốn người khác thừa kế những lỗi tiềm năng của tôi.

0

Cách sử dụng:filterContext.RedirectToAction("Login", "Account");

Dưới đây là một lớp helper tôi đã viết với một số phương pháp mở rộng bằng văn bản để cung cấp chức năng RedirectToAction ở nhiều nơi hơn. Điều này là quá muộn cho OP nhưng hy vọng nó giúp một ai đó!

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

Có nhiều ControllerContexts không được bao gồm nhưng bạn nên thêm khá dễ dàng dựa trên nhu cầu của mình.

Các vấn đề liên quan