ASP.NET中Session的状态保持方式
|
ASP.NET
提供了
Session
对象,从而允许程序员识别、存储和处理同一个浏览器对象对服务器上某个特定网络应用程序的若干次请求的上下文信息。
Session
对应浏览器与服务器的同一次对话,在浏览器第一请求网络应用程序的某个页面时,服务器会触发
Session_onStart
事件;在对话超时或者被关闭的时候会触发
Session_onEnd
事件。
程序员可以在代码中响应这两个事件来处理与同一次对话相关的任务,如开辟和释放该次对话要使用的资源等。
在
ASP.NET
的程序中要使用
Session
对象时,必须确保页面的
@page
指令中
EnableSessionState
属性是
True
或者
Readonly
,并且在
web.config
文件中正确的设置了
SessionState
属性。
ASP.NET
中
Session
的状态保持是由
web.config
文件中的
设为
Off
会禁用
Session.
Inproc
是缺省的设置
,
这种模式和以前的
ASP
的会话状态
的方法是类似的
,
会话的状态会被保存在
ASP.NET
进程中,它的优点是显而易见的:性能。进程内的数据访问自然会比夸进程的访问快。
然而,这种方法
Session
的状态依赖于
ASP.NET
进程,当
IIS
进程崩溃或者正常重起启时,保存在进程中的状态将丢失。
为了克服
Inproc
模式的缺点,
ASP.NET
提供了两种进程外保持会话状态的方法。
ASP.NET
首先提供了提供了一个
Windows
服务:
ASPState
,
这个服务启动后,
ASP.NET
应用程序可以将
mode
属性设置为
“SateServer”,
来使用这个
Windows
服务提供的状态管理方法。
除了在
web.config
文件中设置
mode
属性为
StateServer
外,还必须设置运行
StateServer
服务器的
IP
地址和端口号
.
如果在
IIS
所在的机器运行
StateServer
则
IP
地址就是
127.0.0.1,
端口号通常是
42424.
配置如下:
mode=”StateServer”
stateConnectionString="tcpip=127.0.0.1:42424"
使用这种模式
,
会话状态的存储将不依赖
IIS
进程的失败或者重启
,
会话的状态将存储在
StateServer
进程的内存空间中。
另一种会话状态模式是
SQLServer
模式。这种模式是将会话的状态保存在
SQL Server
数据库中的。使用这种模式前,必须至少有一台
SQL Server
服务器,并在服务器中建立需要的表和存储过程。
.NET SDK
提供了两个脚本来简化这个工作:
InstallSqlState.sql
和
UnInstallSqlState.sql
。这两国文件存放在下面路径中:
<%SYSTEMDRIVER%>/Winnt/Microsoft.NET/Framework/<%version%>/
要配置
SQL Server
服务器,可以在命令行中运行
SQL Server
提供的命令行工具
osql.exe
osql -s [server name] -u [user] -p [password]
例如:
osql -s (local) -u as -p “”-i InstallSqlState.sql
做好必要的数据库准备工作后,将
web.config
文件中的
sessionstate
元素的
mode
属性改为
”sqlserver”,
并指定
SQL
连接字符串。具体如下:
mode="SQLServer"
sqlConnectionString="data source=127.0.0.1;userid=sa;password=;Trusted_Connection=yes"
使用
SQLServer
模式处了可以使
Session
的状态不依赖于
IIS
服务器之外,还可以利用
SQL Server
的集群,使状态存储不依赖于单个的
SQL Server,
这样就可以为应用程序提供极大的可靠性。
|
转(
1
):
Asp.net
默认配置下,
Session
莫名丢失的原因及解决办法
|
正常操作情况下
Session
会无故丢失。因为程序是在不停的被操作,排除
Session
超时的可能。另外,
Session
超时时间被设定成
60
分钟,不会这么快就超时的。
这次到 CSDN 上搜了一下帖子,发现好多人在讨论这个问题,然后我又 google 了一下,发现微软网站上也有类似的内容。 现在我就把原因和解决办法写出来。
原因:
由于
Asp.net
程序是默认配置,所以
Web.Config
文件中关于
Session
的设定如下:
mode
=
'InProc'
stateConnectionString
=
'tcpip=127.0.0.1:42424'
sqlConnectionString
=
'data source=127.0.0.1;Trusted_Connection=yes'
cookieless
=
'true'
timeout
=
'60'
/>
我们会发现 sessionState 标签中有个属性 mode ,它可以有 3 种取值: InProc 、 StateServer?SQLServer (大小写敏感) 。默认情况下是 InProc ,也就是将 Session 保存在进程内( IIS5 是 aspnet_wp.exe ,而 IIS6 是 W3wp.exe ),这个进程不稳定,在某些事件发生时,进程会重起,所以造成了存储在该进程内的 Session 丢失。
[
asp
的
Session
是具有进程依赖性的。
ASP Session
状态存于
IIS
的进程中,也就是
inetinfo.exe
这个程序。所以当
inetinfo.exe
进程崩溃时,这些信息也就丢失。
]
哪些情况下该进程会重起呢?微软的 一篇文章 告诉了我们: 1 、配置文件中 processModel 标签的 memoryLimit 属性 2 、 Global.asax 或者 Web.config 文件被更改 3 、 Bin 文件夹中的 Web 程序( DLL )被修改 4 、杀毒软件扫描了一些 .config 文件。 更多的信息请参考 PRB: Session variables are lost intermittently in ASP.NET applications
解决办法:
前面说到的
sessionState
标签中
mode
属性可以有三个取值,除了
InProc
之外,还可以为
StateServer
、
SQLServer
。这两种存
Session
的方法都是进程外的,所以当
aspnet_wp.exe
重起的时候,不会影响到
Session
。
现在请将 mode 设定为 StateServer 。 StateServer 是本机的一个服务 ,可以在系统服务里看到服务名为 ASP.NET State Service 的服务,默认情况是不启动的。当我们设定 mode 为 StateServer 之后,请手工将该服务启动。 这样,我们就能利用本机的 StateService 来存储 Session 了,除非电脑重启或者 StateService 崩掉,否则 Session 是不会丢的(因 Session 超时被丢弃是正常的)。 除此之外,我们还可以将 Session 通过其他电脑的 StateService 来保存 [ 如使用状态服务器 ] 。具体的修改是这样的。同样还在 sessionState 标签中,有个 stateConnectionString='tcpip=127.0.0.1:42424' 属性,其中有个 ip 地址,默认为本机( 127.0.0.1 ),你可以将其改成你所知的运行了 StateService 服务的电脑 IP ,这样就可以实现位于不同电脑上的 Asp.net 程序互通 Session 了。 如果你有更高的要求,需要在服务期重启时 Session 也不丢失,可以考虑将 mode 设定成 SQLServer ,同样需要修改 sqlConnectionString 属性。关于使用 SQLServer 保存 Session 的操作,请访问 这里 。 在使用 StateServer 或者 SQLServer 存储 Session 时,所有需要保存到 Session 的对象除了基本数据类型(默认的数据类型,如 int 、 string 等)外,都必须序列化。 只需将 [Serializable] 标签放到要序列化的类前就可以了。 如: [Serializable] public class MyClass { ...... } 具体的序列化相关的知识请参 这里 。 至此,问题解决。 参考文章: ASP.NET Session State FAQ ASP.NET Session State [ASP.NET] Session 详解 PRB: Session Data Is Lost When You Use ASP.NET InProc Session State Mode PRB: Session Data Is Lost When You Use ASP.NET InProc Session State Mode ASP.NET HTTP 运行时 .NET 中的对象序列化 |
备注
( 1 )使用 StateServer 模式 确保运行 ASP.NET 状态服务的服务器是要存储会话状态信息的远程服务器。该服务与 ASP.NET 一起安装,其默认位置为
<
驱动器
>:/systemroot/Microsoft.NET/Framework/version/aspnet_state.exe
。
在应用程序的 Web.config 文件中,
设置
mode=StateServer
并设置
stateConnectionString
属性。
例如,
stateConnectionString="tcpip=sarath:42424"
。
( 2 )使用 SQLServer 模式 在运行 SQL Server 的计算机(它将存储会话状态)上运行 InstallSqlState.sql
(默认的安装位置为
<
驱动器
>:/systemroot/Microsoft.NET/Framework/version
)。
这将创建一个名为
ASPState
的数据库,该数据库具有新的存储过程并且在
TempDB
数据库中具有
ASPStateTempApplications
表和
ASPStateTempSessions
表。
在应用程序的 Web.config 文件中,设置 mode=SQLServer 并设置 sqlConnectionString 属性。例如, sqlConnectionString="data source=localhost;Integrated Security=SSPI;Initial Catalog=northwind" 。 ( 3 )示例 以下示例指定若干会话状态配置设置。 timeout="20"/> 要求 包含于: Web 平台: IIS 5.0 、 IIS 5.1 、 IIS 6.0 配置文件: Machine.config 、 Web.config 配置节处理程序: System.Web.SessionState.SessionStateSectionHandler 请参见 ASP.NET 配置 | ASP.NET 设置架构 | SessionStateModule
作者:
来源:
(
责任编辑
:webjx)--- -------------
收集之二
---------------------------------
[
出现原因:
]
在
Windows2003
的服务器中的
IIS6
加入了应用程序池来回收一些无用的进程的功能,当由于网站程序的错误或访问量太多的导致的应用程序池会自动回收该进程,防止网站进入
“
死机
”
状态,而这时候的应用程序池的回收就会导致
session
变量被清除,就出现了
session
变量不见的现象。
为了解决这种在 Windows2003 下才出现的问题,我们在服务端起动 ASP.NET State Service 服务,并且在系统的 machine.config 做了一些改动。现在默认的情况下会话状态 mode 是 StateServer 。如果您的网站根目录下也配有一个 web.config 配置文件,请把 mode="InProc" 改成 mode="StateServer" ,如下代码,就可以防止 session 变量的丢失: stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Integrated Security=SSPI" cookieless="false" timeout="30" /> + |
转(
2
):原因及一些解决之道
|
将
Session
保存在
State Server
里:
1.
启动服务
“ASP.NET State Service”
,
2. 然后,修改 web.config: stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="140000" />
注意
://mode="StateServer"
这种模式下即使修改页面也不会丢失
session!
当然 :mode="InProc" 如果你的模式为这种 , 修改页面的时候会丢失 session!!!!!! 在 WebConfig 里将 Session 的 Mode 设成 SQLServer 或者 StateServer 都不会丢 Session 的,
前者需要写入数据库,后者需要系统开
StateServer
服务
。
|
原因
1
:
bin 目录中的文件被改写, asp.net 有一种机制,为了保证 dll 重新编译之后,系统正常运行,它会重新启动一次网站进程,这时就会导致 Session 丢失,所以如果有 access 数据库位于 bin 目录,或者有其他文件被系统改写,就会导致 Session 丢失。 [ 目录的删除操作一定丢失 session 。 asp.net 的内部机制对待目录有点像个守财奴,它死守着目录,你创建它不会管(往里加),一但创建他就会监视该目录,若你要删除或重命名它的(动它的目录),它就发生重起了。。 ] 原因 2 : 文件夹选项中,如果没有打开 “ 在单独的进程中打开文件夹窗口 ” ,一旦新建一个窗口,系统可能认为是新的 Session 会话,而无法访问原来的 Session ,所以需要打开该选项,否则会导致 Session 丢失 原因 3 : 似乎大部分的 Session 丢失是客户端引起的,所以要从客户端下手,看看 cookie 有没有打开 原因 4 : Session 的时间设置是不是有问题,会不会因为超时造成丢失。
[
默认时间是
20
分钟,可以在
Web.Config
中设置
Session
的
timeOut
,如改为
60
分钟等
]
原因 5 : IE 中的 cookie 数量限制(每个域 20 个 cookie )可能导致 session 丢失 原因 6 : 使用 web garden 模式,且使用了 InProc mode 作为保存 session 的方式 解决丢失的经验 1. 判断是不是原因 1 造成的,可以在每次刷新页面的时候,跟踪 bin 中某个文件的修改时间。 2. 做 Session 读写日志,每次读写 Session 都要记录下来,并且要记录 SessionID 、 Session 值、所在页面、当前函数、函数中的第几次 Session 操作,这样找丢失的原因会方便很多 3. 如果允许的话,建议使用 state server 或 sql server 保存 session ,这样不容易丢失 4. 在 global.asa 中加入代码记录 Session 的创建时间和结束时间,超时造成的 Session 丢失是可以在 SessionEnd 中记录下来的。 5. 如果有些代码中使用客户端脚本,如 javascript 维护 Session 状态,就要尝试调试脚本,是不是因为脚本错误引起 Session 丢失。 |
转(
3
):
Session丢失原因与解决方案小结
|
可能的原因
1
:
win2003 server 下的 IIS6 默认设置下对每个运行在默认应用池中的工作者进程都会经过 20 多个小时后自动回收该进程,造成保存在该进程中的 session 丢失。 因为 Session,Application 等数据默认保存在运行该 Web 应用程序的工作者进程中 , 如果回收工作者进程,则会造成丢失。 解决办法:
修改配置,设置为不定时自动回收该工作者进程,比如设置为当超出占用现有物理内存
60
%后自动回收该进程。通过使用默认应用程序池,可以确保多个应用程序间互相隔离,保证由于一个应用程序的崩溃不会影响另外的
Web
应用程序。还可以使一个独立的应用程序运行在一个指定的用户帐号特权之下。如果使用
StateServer
方式或者
Sql Server
数据库方式
来保存
Session,
则不受该设置的影响。
可能的原因 2 :
系统要运行在负载平衡的
Web
场环境
中,而系统配置文件
web.config
中的
Session
状态却设置为
InProc
(即在本地存储会话状态)
,导至在用户访问量大时,
Session
常经超时的情况。引起这个现象的原因主要是因为用户通过负载平衡
IP
来访问
WEB
应用系统,某段时候在某台服务器保存了
Session
的会话状态,但在其它的
WEB
前端服务器中却没有保存
Session
的会话状态,而随着并发量的增大,
负载平衡会当作路由随时访问空闲的服务器,结果空闲的服务器并没有之前保存的
Session
会话状态
。
解决办法: 1. 当您在负载平衡的 Web 场环境中 运行 ASP.NET Web 应用程序时,一定要使用 SqlServer 或 StateServer 会话状态模式 , 在项目中我们基于性能考虑并没有选择 SqlServer 模式来存储 Session 状态,而是选择一台 SessionStateServer 服务器来用户的 Session 会话状态 。我们要在系统配置文件 web.config 中设置如下:
mode="StateServer"
cookieless="false" timeout="240"
stateConnectionString
="tcpip=192.168.0.1:42424" stateNetworkTimeout="14400" />
还要添加一项
validationKey
="78AE3850338BFADCE59D8DDF58C9E4518E7510149C46142D7AAD7F1AD49D95D4" decryptionKey="5FC88DFC24EA123C" validation="SHA1"/> 2. 我们同时还要在 SessionStateServer 服务器中启动 ASP.NET State Service 服务 ,具体设置:控制面板 >> 管理工具 >> 服务 >>ASP.NET State Service ,把它设为自动启动即可。 3. 每台前端 WEB 服务的 Microsoft“Internet 信息服务 ”(IIS) 设置 要在 Web 场中的不同 Web 服务器间维护会话状态, Microsoft“Internet 信息服务 ”(IIS) 配置数据库中 Web 站点的应用程序路径(例如, /LM/W3SVC/2 )与 Web 场中所有 Web 服务器必须相同。大小写也必须相同,因为应用程序路径是区分大小写的。在一台 Web 服务器上,承载 ASP.NET 应用程序的 Web 站点的实例 ID 可能是 2 (其中应用程序路径是 /LM/W3SVC/2 )。在另一台 Web 服务器上, Web 站点的实例 ID 可能是 3 (其中应用程序路径是 /LM/W3SVC/3 )。因此, Web 场中的 Web 服务器之间的应用程序路径是不同的。我们必须使 Web 场 Web 站点的实例 ID 相同即可。你可以在 IIS 中把某一个 WEB 配置信息保存为一个文件,其他 Web 服务器的 IIS 配置可以来自这一个文件。您如果想知道具体的设置请访问 Microsoft Support 网站: |
转(4):丢失问题集锦
|
SessionState
的
Timeout)
,其主要原因有三种。
一:有些杀病毒软件会去扫描您的 Web.Config 文件,那时 Session 肯定掉,这是微软的说法。 二 : 程序内部里有让 Session 掉失的代码,及服务器内存不足产生的。 三:程序有框架页面和跨域情况。 第一种解决办法是 : 使杀病毒软件屏蔽扫描 Web.Config 文件 ( 程序运行时自己也不要去编辑它 ) 第二种是检查代码有无 Session.Abandon() 之类的。 第三种是在 Window 服务中将 ASP.NET State Service 启动。
http://community.csdn.net/Expert/topic/3100/3100218.xml?temp=.4426386
还有可能就是你在测试期间改动了,网站的文件。 下面是帮助中的内容 : (ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconsessionstate.htm) ASP.NET 提供一个简单、易于使用的会话状态模型,您可以使用该模型跨多个 Web 请求存储任意数据和对象。
它使用基于字典的、内存中的对象引用(这些对象引用存在于
IIS
进程中)缓存来完成该操作。
使用进程内会话状态模式时请考虑下面的限制:
使用进程内会话状态模式时,如果
aspnet_wp.exe
或应用程序域重新启动,则会话状态数据将丢失。这些重新启动通常会在下面的情况中发生:
( 1 ) 在应用程序的 Web.config 文件的
(
2
)修改
Global.asax
或
Web.config
文件。
(
3
)更改到
Web
应用程序的
/Bin
目录。
( 4 ) 用杀毒软件扫描并修改 Global.asax 文件、 Web.config 文件或 Web 应用程序的 /Bin 目录下的文件。 ( 5 ) 如果在应用程序的 Web.config 文件的
我也碰到过。本机器上的
Session
或者
Cookie
丢失。
stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="40" /> mode="" 很多网络架构,各个服务器之间都是通过一台专门保存状态的服务器(专门的状态服务器)来保存比如说 session,cookie..
我以前遇到这种问题,我用了以下几个方法来解决。现在也没有这种情况发生了。
1、 release ,不要 debug 发布。 2、 3、在 IIS 中把 Session 过期时间延长。 4、让杀毒软件不扫描 bin 文件夹下的文件和 Web.Config 文件 。 以上我是不明不白的做的。不过 Session 正常使用了!呵呵 ~~ 我幸运 !
没啥好讲的,不要用
Session
好了,直接用
Forms
认证
把,
我前两天的系统就是用这个搞定的,觉得挺好的。
刚碰到一个类似的问题:在使用
frameset
的时候,
session
变量丢失。
在微软的网站上找到了解决的方法 http://support.microsoft.com/kb/323752/EN-US/ 不知道是否有用? IIS--->> 应用程序连接池 --->> 属性 ---->>[ 回收 ][ 性能 ][ 运行状况 ] 里的各项参数 尽量都往大的改 ^_^), 我不知道改拉那个才对的 , 反正我改完后所有的 session 都好拉 . 客户的网站和动网论坛的后台也跟着好拉。 |
转(5): 模态窗口中打开新窗口的session丢失
|
一直被这个问题郁闷。
在窗口
A
中使用
showModalDialog()
打开了一个新的模态窗口
B
。然后在
B
窗口中进行一些业务操作,最后还需要根据业务操作打印一些表单,结果此时在
B
中调用
open()
方法就会出现
session
丢失的现象,
提示用户重新登陆。
两天来一直没头苍蝇一样不停的试验各种方法。如果在这个窗口中采用打开非模态对话框的打开方法
showModelessDialog()
就没有任何问题,但是直接使用
open()
方法就是不能达到想要的效果。
在网上不停的
google
,到各大
bbs
寻找解答,提供的都是最简单的应用。好不容易找到一篇文章,其中提到
session
对象的有效范围,
却也没有具体提到我遇到的问题:
IE
中
:
有效的窗品包括
1.Session
对象只在建立
Session
对象的窗口中有效。
2.
在建立
Session
对象的窗口中新开链接的窗口
无效的窗口包括
1.
直接启动
IE
浏览器的窗口
2.
不是在建立
Session
对象的窗口中新开链接的窗口。(即作者在建立
Session
对象的
A
窗口弹出的
B
窗口上调用了
open()
方法。)
考虑只在建立
session
对象的窗口中有效,于是就在子窗口中重新使用
session.setAttribute()
方法,以为如此就可以成功,结果还是不行,郁闷。
早上起来突然来了灵感,既然子窗口中造成了
session
丢失,在父窗口中是无论如何还存在着
session
的变量的,我可以不必在子窗口中重新设置
session
变量,而可以直接调用父窗口的
javascript
函数
open()
方法可能会到目的吧。
不管如何先试试,结果果然如此。
很多时候问题就是这样的,想要偷懒,于是不自己钻研,到处寻求解答,最后还是得靠自己来搞定。
|