2011-03-27 76 views
106

ActionFilterAttribute中执行重定向的最佳方式是什么?我有一个名为IsAuthenticatedAttributeFilterActionFilterAttribute并检查了会话变量的值。如果该变量为false,我希望应用程序重定向到登录页面。我宁愿使用路由名称SystemLogin重定向,但是此时任何重定向方法都可以。从动作重定向过滤器属性

+2

** [检查这个答案。希望这会对你有所帮助。](http://stackoverflow.com/a/18126733/2015869)** – 2013-08-12 08:53:51

回答

152

集filterContext.Result

随着路由名称:

filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues); 

你也可以这样做:

filterContext.Result = new ViewResult 
{ 
    ViewName = SharedViews.SessionLost, 
    ViewData = filterContext.Controller.ViewData 
}; 

如果你想使用RedirectToAction

你可以做(​​最好是在它的基础控制器),简单地调用从System.Web.Mvc.Controller保护RedirectToAction您的控制器上的公共RedirectToAction方法。添加此方法允许从过滤器公开呼叫 RedirectToAction

public new RedirectToRouteResult RedirectToAction(string action, string controller) 
{ 
    return base.RedirectToAction(action, controller); 
} 

那么你的过滤器看起来是这样的:

public override void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
    var controller = (SomeControllerBase) filterContext.Controller; 
    filterContext.Result = controller.RedirectToAction("index", "home"); 
} 
+7

这可行,但不应该有一个RedirectToAction方法可用? – 2012-02-21 19:28:35

+0

@BenMills然而,它是'受保护的',所以你不能从过滤器访问它。 – James 2014-02-15 10:14:42

+7

我现在的问题是为什么微软决定让这个过滤器保护'必须有一些合理的解释?我觉得非常脏,重新定义'RedirectToAction'的这种可访问性,而不理解它为什么被封装在第一位。 – 2015-03-25 11:30:50

9

这听起来像你想重新实现,或可能延长,AuthorizeAttribute。如果是这样,你应该确保你继承了那个,而不是ActionFilterAttribute,以便让ASP.NET MVC为你做更多的工作。

而且,你要确保你授权你做之前的任何实际工作的操作方法 - 否则之间的唯一区别登录,而不是将你所看到的页面,当工作完成。

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     // Do whatever checking you need here 

     // If you want the base check as well (against users/roles) call 
     base.OnAuthorization(filterContext); 
    } 
} 

有一个很好的questionanswer与这里SO更多细节。

4

试试下面的代码片段,它应该是很清楚的:

public class AuthorizeActionFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(FilterExecutingContext filterContext) 
    { 
    HttpSessionStateBase session = filterContext.HttpContext.Session; 
    Controller controller = filterContext.Controller as Controller; 

    if (controller != null) 
    { 
     if (session["Login"] == null) 
     { 
     filterContext.Cancel = true; 
     controller.HttpContext.Response.Redirect("./Login"); 
     } 
    } 

    base.OnActionExecuting(filterContext); 
    } 
} 
+0

这对我有用,如果任何用户试图更改查询字符串值并尝试访问未授权给他/她的数据,则我必须检查查询字符串值,而不是使用ActionFilterAttribute将其重定向到未授权的消息页面。 – Sameer 2013-05-23 06:56:28

+0

这很好。谢谢! – 2013-06-07 15:43:28

1

,你可以继承你的控制器,然后用它你的动作过滤器

里面你ActionFilterAttribute类中:

if(filterContext.Controller is MyController) 
     if(filterContext.HttpContext.Session["login"] == null) 
      (filterContext.Controller as MyController).RedirectToAction("Login"); 

在您的底座控制器内部:

public class MyController : Controller 
{ 
    public void RedirectToAction(string actionName) { 
     base.RedirectToAction(actionName); 
    } 
} 

缺点。这是改变所有控制器从“myController的”类继承

56

另外一个重定向,如果调用自己的代码,你可以这样做:

actionContext.Result = new RedirectToRouteResult(
    new RouteValueDictionary(new { controller = "Home", action = "Error" }) 
); 

actionContext.Result.ExecuteResult(actionContext.Controller.ControllerContext); 

它不是一个纯粹的重定向,但给出了类似的结果没有不必要的开销

+0

你帮我。谢谢! – 2015-01-08 16:13:59

+0

这是正确的答案。 – 2015-02-27 15:09:27

+12

请注意,您不应该在您的操作过滤器内调用actionContext.Result.ExecuteResult - MVC将在操作过滤器运行后自动执行此操作(提供的actionContext.Result不为空)。 – NightOwl888 2016-02-24 19:41:58

10

我正在使用MVC4,我使用以下方法在授权违反时重定向自定义html屏幕。

扩展AuthorizeAttributeCutomAuthorizer 覆盖的OnAuthorizationHandleUnauthorizedRequest

RegisterGlobalFilters注册CustomAuthorizer

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 

    filters.Add(new CustomAuthorizer()); 
} 

在识别unAuthorized接入呼叫HandleUnauthorizedRequest和如下所示重定向到所关注的控制器动作。


public class CustomAuthorizer : AuthorizeAttribute 
{ 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     bool isAuthorized = IsAuthorized(filterContext); // check authorization 
     base.OnAuthorization(filterContext); 
     if (!isAuthorized && !filterContext.ActionDescriptor.ActionName.Equals("Unauthorized", StringComparison.InvariantCultureIgnoreCase) 
      && !filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.Equals("LogOn", StringComparison.InvariantCultureIgnoreCase)) 
     { 

      HandleUnauthorizedRequest(filterContext); 

     } 
    } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     filterContext.Result = 
     new RedirectToRouteResult(
      new RouteValueDictionary{{ "controller", "LogOn" }, 
              { "action", "Unauthorized" } 

             }); 

    } 
} 
相关问题