我正在使用ASP.NET MVC3构建一个网站。当用户登录时,我从数据库中提取他们的显示名称并将其存储到会话变量:
Session["DisplayName"] = user.Display;
然后在_Layout.cshtml
我用它来显示每页的顶部:
<span class="user">@(Session["DisplayName"] as string)</span>
当我开始调试网站然后登录时,这工作正常,但如果我重建我的服务器并再次开始调试,我的浏览器仍然会登录,但Session
变量已被清除。这导致了一堆空格,我的显示名称应该是。
这是重建服务器的副作用,而不是我需要在部署中担心的事情吗?有没有办法在每次重建时使登录失效,以便我避免这个问题?或者除了Session
变量之外,还有更好的方法来存储此用户数据吗?
答案 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?