首次加载时,如何/如何在MVC应用中使用存储在cookie数据中的用户填充会话?

时间:2012-02-16 20:00:31

标签: asp.net-mvc session cookies login forms-authentication

我有一个存储我的整个用户对象的会话变量,当这个人使用表单身份验证登录我的站点时(使用默认的MVC提供的登录)我将Session变量设置为用户对象,如下所示:

FormsAuthentication.SetAuthCookie(user.Username, model.RememberMe);
SessionUtil.User = user;

我的所有页面都设置为使用此Session对象,但是当他们检查“记住我”框时会出现问题。关闭浏览器,重新打开浏览器,然后再次访问我的网站。此时会话很清楚,他们没有登录,但我的网站仍记得他们是谁,但是会话中断了所有引用我的用户对象的页面。

我正在寻找一种方法来使用适当的数据填充Session用户对象,这样在上面的场景中,无论在访问我的网站后他们在“记住”时首先遇到什么页面,会话对象都不会为空。这样做的好地方在哪里?在应用程序启动?在SessionUtil中(现在它只是会话变量的静态包装器)?控制器上的基类?我该怎么做?我已经编写了逻辑来让用户忘记用户名。

修改:应用程序启动似乎不是一个好地方,因为这样做:

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

仍然显示我已登录,并且用户名在那里显示正常。

1 个答案:

答案 0 :(得分:3)

你绝对不想使用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只是一个内存存储区,可供每个唯一用户使用,经过身份验证或不