会话变量在开发过程中的工作方

时间:2012-06-18 20:08:05

标签: asp.net asp.net-mvc-3 session

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

Session["DisplayName"] = user.Display;

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

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

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

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

3 个答案:

答案 0 :(得分:4)

  

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

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

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

答案 1 :(得分: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();
} 

答案 2 :(得分:0)

有更好的方法,但是为了解决您的特定问题,您的auth超时和会话超时不一样,您需要专门处理这个案例,当一个人在另一个之前超时。在这里看我的帖子:

How can I handle forms authentication timeout exceptions in ASP.NET?