3

我正在使用 ASP.NET MVC3 构建一个网站。当用户登录时,我从数据库中提取他们的显示名称并将其存储到会话变量中:

Session["DisplayName"] = user.Display;

然后在_Layout.cshtml我用它显示在每一页的顶部:

<span class="user">@(Session["DisplayName"] as string)</span>

当我开始调试网站然后登录时,这工作正常,但是如果我随后重建服务器并再次开始调试,我的浏览器仍然保持登录状态,但Session变量被清除。这会导致我的显示名称应该是一堆空白。

这是重建服务器的副作用,而不是我在部署时需要担心的事情吗?有没有办法在我每次重建时使登录无效,从而避免这个问题?或者有没有更好的方法来存储这个用户数据,而不是一个Session变量?

4

3 回答 3

4

这是重建服务器的副作用,而不是我在部署时需要担心的事情吗?

哦不,这是你绝对应该担心的事情。如您所知,ASP.NET 会话默认存储在服务器内存中。并且当 IIS 回收 AppDomain(这绝对可能在任何时候发生)时,您的所有会话都消失了。例如,在应用程序处于某种不活动状态后,IIS 可能会关闭 AppDomain。或者在达到某些 CPU 或内存使用阈值之后。如果您希望能够在 ASP.NET 会话中可靠地存储某些内容,您可以卸载存储过程外并将该会话存储在专用会话服务器或 SQL 中。但老实说,我看到很多人将 ASP.NET Session 迁移到 SQL Server 并后悔。重点是什么?您已经在 SQL Server 中获得了这些信息 :-) 我曾经使用过它并且非常后悔。

我个人从不在我的应用程序中使用 ASP.NET Session。如果您需要保留显示名称等信息并避免在每次请求时访问数据库,您可以将其存储在表单身份验证 cookie 的用户数据部分。所以这里的想法是:当用户成功输入正确的凭据时,您手动创建一个FormsAuthenticationTicketUserData 属性,并使用您希望在每个请求中获得有关此用途的任何信息填充其 UserData 属性,然后发出身份验证 cookie。然后,您编写一个自定义 Authorize 属性,在其中解密 cookie,获取用户数据并将其存储为自定义IIdentity,使其在每个请求中都可用。

于 2012-06-18T20:10:05.707 回答
1

将用户名存储在缓存(Cache[string.Format("DisplayName_{0}", User.Id)] = User.Username)、cookie 或将会话移动到 SQL Server 而不是 InProc

我将创建一个通过用户 ID 获取用户名的静态辅助方法。如果找到缓存的值,它将使用该值,如果没有,则从 db 获取值,将其存储在缓存中并返回。

public static string GetUsername(int UserID)
{
    string cacheKey=string.Format("DisplayName_{0}", UserID);
    if (HttpContext.Current.Cache[cacheKey]==null)
    {
        // Retrieve user name from DB
        string Username=Repository.GetUserName(UserID);
        HttpContext.Current.Cache[cacheKey]=Username;
    }

    return HttpContext.Current.Cache[cacheKey].ToString();
} 
于 2012-06-18T20:12:25.663 回答
0

有更好的方法,但是要解决您的特定问题,您的身份验证超时和会话超时不一样,您需要专门处理一个在另一个之前超时的情况。在这里查看我的帖子:

如何在 ASP.NET 中处理表单身份验证超时异常?

于 2012-06-18T20:30:01.887 回答