通常情况下我们使用Session一般都是为了记录用户的登陆状态以及信息,用于登陆验证,但是默认情况下(InProc模式),我们的Session都是保存到当前进程中,当该进程被重启,Session就会丢失。
也就是说,大部分情况下,会因为下面两种情况的操作导致Session丢失而需要重新登陆
1.Global.asax或者Web.config文件被更改
2.Bin文件夹中的Web程序(DLL)被修改
其中比较常见不好的体验是:当我们重新发布程序的时候,因为Session丢失,别人在操作后台的时候会跳出到登录页
这个时候若我们使用StateServer模式进行存放Session,则不会出现这种因修改文件或重新发布而丢失Session的问题了
原理为:保存Session到独立windows进程,要使用这种方法,需要打开aspnet_state.exe服务,通过此方法,我们可以将Session保存到本地主机或者其它服务器,这样可以实现多台服务器的session共享,且会话状态数据比较稳定,除非电脑重启或者StateService服务崩掉,否则Session是不会丢的(因Session超时被丢弃是正常的)。
解决方法:
第一步:开启ASP.Net State Service服务
第二步:
在web.config文件添加(因为博客文章显示原因,在<符号后面增加了一个空格,实际使用去掉空格即可)
< system.web> < sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42626" cookieless="false" timeout="20" /> < /system.web>
其中tcpip=127.0.0.1:42626的127.0.0.1是服务器ip,如果是本地就为127这个,并且端口号是42626)
第三步:
由于ASP.NET 将序列化会话状态对象,因此不允许使用无法序列化的对象,如果你的Session存储的内容是对象,则必须需要将该对象序列化,也就是需要在对象实体的Class上添加 [Serializable]
最后大功告成~~
Tip:
sessionState节点的语法是这样的:
< sessionState mode="Off|InProc|StateServer|SQLServer" cookieless="true|false" timeout="number of minutes" stateConnectionString="tcpip=server:port" sqlConnectionString="sql connection string" stateNetworkTimeout="number of seconds" />
必须有的属性是:
mode 设置将Session信息存储到哪里
Off 设置为不使用Session功能
InProc 设置为将Session存储在进程内,就是ASP中的存储方式,这是默认值。
StateServer 设置为将Session存储在独立的状态服务中。
SQLServer 设置将Session存储在SQL Server中。
cookieless 设置客户端的Session信息存储到哪里
ture 使用Cookieless模式
false 使用Cookie模式,这是默认值。
timeout 设置经过多少分钟后服务器自动放弃Session信息。默认为20分钟
stateConnectionString 设置将Session信息存储在状态服务中时使用的服务器名称和端口号,例如:”tcpip=127.0.0.1:42424”。当mode的值是StateServer是,这个属性是必需的。
sqlConnectionString 设置与SQL Server连接时的连接字符串。例如”data source=localhost;Integrated Security=SSPI;Initial Catalog=northwind”。当mode的值是SQLServer时,这个属性是必需的。
stateNetworkTimeout 设置当使用StateServer模式存储Session状态时,经过多少秒空闲后,断开Web服务器与存储状态信息的服务器的TCP/IP连接的。默认值是10秒钟。