2013-09-22 64 views
0

我有一个ASP.NET MVC4应用程序。我创建了一个登录页面。如果用户登录系统,我将用户信息注册到会话中。我添加了一个检查会话变量的过滤器。如果用户没有登录到系统,我想将用户重定向到我的登录控制器。ASP.NET MVC4 ActionFilters

public class SecurityAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (filterContext.HttpContext.Session["User"] == null) 
      { 
       filterContext.HttpContext.Response.RedirectToRoute("Default", new 
       { 
        controller = "Login", 
        action = "DoLogin", 
        returnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri 
       }); 
      } 
      base.OnActionExecuting(filterContext); 
     } 
    } 

我在控制器级使用这个属性。

[SecurityAttribute] 
    public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      ViewData["Name"] = ((UserEntity)Session["User"]).Name; 
      ViewData["Surname"] = ((UserEntity)Session["User"]).Surname; 
      return View(); 
     } 
    } 

OnActionExecuting方法在动作执行之前触发,但在我的主控制器中的动作方法之后重定向occures。因为会话变量为空,所以在索引操作中出现错误。我怎样才能解决这个问题?

回答

2

如果要短路控制器操作的执行,则应该在filterContext上分配Result属性。就这样:

public class SecurityAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext.HttpContext.Session["User"] == null) 
     { 
      var values = new 
      { 
       controller = "Login", 
       action = "DoLogin", 
       returnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri 
      }; 
      var result = new RedirectToRouteResult("Default", new RouteValueDictionary(values)); 

      filterContext.Result = result; 
     } 
    } 
} 

而且它会一直在语义上更正确的编写用于此目的的授权过滤器,并依靠内置的窗体身份验证,而不是与会话和东西重塑车轮。

所以干脆:

[Authorize] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     string username = User.Identity.Name; 
     SomeUserModel user = GetUserFromBackend(username); 
     return View(user); 
    } 
} 

您可以在MSDN阅读更多关于表单验证:http://msdn.microsoft.com/en-us/library/ff647070.aspx