【问题标题】:SessionManager and Session is null randomlySessionManager 和 Session 随机为空
【发布时间】:2013-12-06 23:12:13
【问题描述】:

几个月来我一直面临这个问题,我已经阅读了几乎所有关于此的内容并实施了大多数解决方案,但仍然没有任何改变。我不知道我在哪里犯错了。

我正在使用自定义 SessionManager 类在我的 ASP.net CMS 网站的管理面板中轻松获取/设置值到 Session。当用户登录时,我将用户数据存储到Session,然后在 Admin.master 页面中读取以检查用户是否已登录。在不同的服务器和本地主机上,SessionManager.CurrentUser 值随机为空,有时为 2分钟有时登录后 20 分钟,无论页面是否空闲。我所有的网站都有同样的问题。

我的 SessionManager.cs 是

public class SessionManager
{
    public SessionManager() { }

    public static User CurrentUser
    {
        get { return (User)HttpContext.Current.Session["crntUsr"]; }
        set { HttpContext.Current.Session["crntUsr"] = value; }
    }

    public static string CurrentAdminLanguage
    {
        get
        {
            if (HttpContext.Current.Session["crntLang"] == null) HttpContext.Current.Session["crntLang"] = SiteSettings.DefaultLanguage;
            return HttpContext.Current.Session["crntLang"].ToString();
        }
        set
        {
            HttpContext.Current.Session["crntLang"] = value;
        }
    }
}

注意:用户类是 [Serializable]

在 Admin.master Page_Load 中

if (SessionManager.CurrentUser == null) Response.Redirect("../login");

在 web.config 中

    <system.web>
         <sessionState mode="InProc" customProvider="DefaultSessionProvider" cookieless="UseCookies" regenerateExpiredSessionId="true" timeout="60"/>
         <machineKey validationKey="CC0...F80" decryptionKey="8BF...1B5" validation="SHA1" decryption="AES"/>
         <authentication mode="Forms">
             <forms loginUrl="~/login" timeout="60" slidingExpiration="true" cookieless="UseCookies" />
         </authentication>

    <system.webServer>
        <modules>
            <remove name="Session"/>
            <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
        </modules>

我真的没有更多的想法来解决这个问题。请帮忙:(

【问题讨论】:

标签: c# asp.net session


【解决方案1】:

您是否检查过您的应用程序池回收超时?这是会话比预期提前“消失”的常见问题。签入 IIS

【讨论】:

  • 我又检查了一遍。 AppPool 超时,Forms 超时和 sessionstate 超时都是相同的值 60。现在,我似乎没有问题,但仍然不确定它是否正常。
  • 对于我的一个网站,我联系了托管公司,他们说不可能为每个网站更改此回收超时,因此我应该购买 VDS 服务器。是否可以为每个网站配置应用程序池回收超时?
  • 如果您处于托管状态,那么您几乎没有机会。任何可能导致应用程序池回收的(内部或外部)都会中断您的会话。因此,您应该按照其他答案中的建议传递给另一种类型的会话管理(例如在 DB 上)
  • 好的。除非我得到服务器,否则我会尝试切换到 SqlServer 模式。我想知道大型应用程序如何管理如此多的会话?
【解决方案2】:

如果遇到问题,可以设置 SQL Server 来处理会话,如果 AppPool 被回收,或者服务器重新启动,它将保持它。

欲了解更多信息:http://support.microsoft.com/kb/317604

【讨论】:

  • 这太奇怪了,InProc 不能正常工作,如果我能解决这个问题,一切都会好起来的。我认为 InProc 应该足以满足需求。我已经为几个项目实施了我的 CMS,所以你的建议将是我最后的机会。还是谢谢。
  • 这个问题可能有很多原因。阅读本文以了解 AppPool 回收:petesbloggerama.blogspot.se/2007/10/…
  • 我有时在本地主机上遇到这个问题。 ASP.Net 开发服务器是否也有应用程序回收超时?也许由于内存或进程回收,我在 localhost 上遇到了这个问题。
【解决方案3】:

这是一个示例 web.config 代码。我不喜欢那里的 regenerateExpiredSessionId,而且让会话超时小于表单超时也是一个好习惯。我的建议是仔细检查您的会话管理器代码,以确保您不会以某种方式重置它。我能想到你可以做的两件事: 1. 制作一个测试页面来检查会话何时为空,并查看是否可以设置会话变量。尝试单击按钮(或 ajax 请求)并设置会话变量以使会话每隔 1 分钟左右保持活动状态,以查看它是否再次过期,即使您保持活动状态也是如此。如果您不使用 Session 它将过期。 2. 做一些记录。每次设置会话变量时,都会记录您设置的变量的数据库日志。您可以使用 1 中的测试页面来查看您在会话中为当前用户设置的具体内容。

<authentication mode="Forms">
  <forms name="Web-site.ASPXAUTH" loginUrl="~/admin/login.aspx" protection="All" timeout="60" path="/" requireSSL="false" slidingExpiration="true" cookieless="UseDeviceProfile" domain="" enableCrossAppRedirects="false" />
</authentication>
<sessionState timeout="60" mode="InProc" />
<membership defaultProvider="WebSiteMembershipProvider">
  <providers>
    <clear />
    <add name="WebSiteMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="DefaultConnStr" applicationName="web-site" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" enablePasswordReset="true" enablePasswordRetrieval="false" passwordFormat="Hashed" requiresUniqueEmail="false" />
  </providers>
</membership>
<roleManager defaultProvider="WebSiteRoleProvider" enabled="true" cacheRolesInCookie="true" cookieName="Web-Site.ASPXROLES" cookieTimeout="60" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All" createPersistentCookie="false" maxCachedResults="25">
  <providers>
    <clear />
    <add name="WebSiteRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="DefaultConnStr" applicationName="web-site" />
  </providers>
</roleManager>

【讨论】:

  • 我认为 WebSiteMembershipProvider 是自定义提供程序,对吗?记录会话是一个好主意,我已经尝试过并且没有看到任何壮观的东西。我想我会转移到 SqlServer 模式会话以保证会话。我不知道在那种模式下我会遇到什么样的问题:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多