2009-06-18 62 views
3

我基本上使用ASP.NET MVC示例中的AccountController。它使用FormsAuthentication来处理用户登录。只是可以肯定,这里是代码来处理用户登录:登录后在ActionFilter中检查User.Identity.IsAuthenticated

public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl) 
    { 
     if (!ValidateLogOn(userName, password)) 
     { 
     return View(); 
     } 

     FormsAuth.SignIn(userName, rememberMe); 


     //Session["userId"] = 1; 


     if (!String.IsNullOrEmpty(returnUrl)) 
     { 
     return Redirect(returnUrl); 
     } 
     else 
     { 
     return RedirectToAction("Index", "Home"); 
     } 
    } 

你可以从注释行看到,我想设置一个会话变量在此方法。但是,我认为这不是直接在控制器中设置Session变量的最优雅方式。单元测试这种方法也是不方便的(虽然我可以嘲笑它,当然,但仍然)。

所以,我想,我创建了一个自定义的ActionFilterAttribute,在此登录例程之后运行。如果登录成功,请在此自定义属性中设置会话变量。这个代码是:

public class SetSessionAttribute : ActionFilterAttribute 
    { 
    public override void OnResultExecuted(ResultExecutedContext resultContext) 
    {  
     if (resultContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
     resultContext.HttpContext.Session["userId"] = 1; 
     } 

     base.OnResultExecuted(resultContext); 
    } 
    } 

的问题是,User.Identity.IsAuthenticated始终返回false,直到下一个“页面加载”。我在覆盖OnResultExecuted,因为我收集它是在页面生命周期中调用的最后一种方法,但没有运气。我也试过OnActionExecuting,OnActionExecutedOnResultExecuting,但它总是假的。

有没有一个优雅的解决方案呢?还是应该放弃并直接在控制器中设置会话变量?

回答

0

我在注销时遇到类似问题,因为User.Identity.IsAuthenticated在下一个页面请求之前是真实的,但我需要一种方法来知道用户是否真的完成了应用程序的工作。

我想你应该在控制器中设置Session或ViewData变量或通过routeValues传递给另一个控制器。

+0

感谢您的回复。是的,我可以在控制器中设置会话,但这正是我试图避免的。我仍然希望有一个可行的替代方案。 – Razzie 2009-06-19 10:03:08