我有一个会话变量来存储我的整个用户对象,当这个人使用表单身份验证登录我的站点时(使用默认的MVC提供的登录)我将Session变量设置为用户对象,如下所示:
FormsAuthentication.SetAuthCookie(user.Username,model.RememberMe); SessionUtil.User = user;
我的所有页面都设置为使用此Session对象,但是当他们检查“记住我”框时会出现问题.关闭浏览器,重新打开浏览器,然后再次访问我的网站.此时会话很清楚,他们没有登录,但我的网站仍记得他们是谁,但是会话中断了所有引用我的用户对象的页面.
我正在寻找一种方法来使用适当的数据填充Session用户对象,这样在上面的场景中,无论在访问我的网站后他们在“记住”时首先点击什么页面,会话对象都不会为空.这样做的好地方在哪里?在应用程序启动?在SessionUtil中(现在它只是会话变量的静态包装器)?控制器上的基类?我该怎么做?我已经编写了逻辑来让用户关闭用户名.
编辑:好吧application_start似乎不是一个好地方,因为这样做:
if (User != null) { SessionUtil.User = EntityServiceFactory.GetService<UserService>().GetUser(User.Identity.Name); }
在该方法中不会阻止问题的发生.我尝试在if检查中执行User.Identity.Name然后我得到一个空引用异常,但我仍然记得并在页面实际加载时登录.
根据Splash-X的评论在Global.asax中尝试以下内容:
protected void Application_BeginRequest() { if(User != null) { SessionUtil.User = EntityServiceFactory.GetService<UserService>().GetUser(User.Identity.Name); } }
此事件正在运行每个请求,但User始终为null.但我没有得到的是默认的_logonPartial代码:
@if(Request.IsAuthenticated) { <text><strong>@User.Identity.Name</strong> [@Html.ActionLink("Profile","Profile","Account")] [ @Html.ActionLink("Log Off","logoff","Account") ]</text> }
解决方法
你肯定不想使用application_start – 这只运行一次,在你的应用程序开始旋转时.您可能正在寻找的是session_start,它将在新会话的第一个请求时运行:
void Session_Start(object sender,EventArgs e) { // set SessionUtil.User here }
我不认为有必要刷新您的用户对象的确切答案.如果我必须选择,我可能会在你的SessionUtil.User getter中做到这一点.这样的事情(警告,我没有编译或测试这个)
public User User { get { if (Session["user"] != null) return Session["user"] as User; var user = GetUser(); //however you normally get current user Session["user"] = user; return user; } }
最终结果是,您无法请求会话实用程序的User属性为null.
编辑:为了清楚,会话与被“记住”无关.您的站点知道您已登录并进行身份验证,因为您拥有ASP.NET授权cookie.这与Session无关. Session只是一个范围内存存储器,可供每个唯一用户使用,是否经过身份验证.