HTTP 是一种无状态协议。这意味着 Web 服务器会将针对页面的每个 HTTP 请求作为独立的请求进行处理。ASP.NET 会话状态将来自限定时间范围内的同一浏览器的请求标识为一个会话,并提供用于在该会话持续期间内保留变量值的方法。默认情况下,将为所有 ASP.NET 应用程序启用 ASP.NET 会话状态。当用户在 Web 应用程序中导航 ASP.NET 页时,ASP.NET 会话状态使您能够存储和检索用户的值。
在阅读完MSDN的文档后个人对会话状态的关注点有标识符,模式还有事件。
Session标识符
Seesion在鄙人大学时学习ASP.NET WebForm的时候就接触到,当时是以Page类的内置对象来介绍。当时结合这里的理解,Session对象实际上是用于保存一个会话中所需要保留下来的值的一个字典集合。而在服务器中接受了多个用户的访问请求后,会产生多个会话,这些会话对应的Session也是以一个字典集的形式保存起来。Session内的值对应的标识符是由开发人员自己定义,而每个Session对象的标识符是由一个SessionIDManager来提供,这个SessionIDManager可以开发自己定义。服务器每次接受到一个请求时,都会检查这个请求中是否带了会话的标识符,默认是存储在cookie中的ASP.NET_SessionId,如果没有则通过SessionIDManager的CreateSessionID方法创建一个,然后响应的时候把这个SessionIDManager告诉浏览器,那么以后每次发请求的时候都会带着这个ASP.NET_SessionId的Cookie发到服务端,表明这一系列的请求都属于一个会话。
当在 Web.config 文件的 sessionState 节中将 cookieless 属性设置为 TRUE或UseUri,可以指定不将会话标识符存储在 cookie 中。ASP.NET 通过自动在页的 URL 中插入唯一的会话 ID 来保持无 cookie 会话状态。例如,下面的 URL 已被 ASP.NET 修改,以包含唯一的会话 ID lit3py55t21z5v55vlm25s55:
但凡使用了这种形式的Session配置时,在将每页发送到浏览器之前,在链接中嵌入一个会话 ID 值。只要用户遵循 ASP.NET 应用程序提供的链接路径,即可保持会话状态,否则像平时的把请求重定向或者或者跳转到某个URL时,
如上面所示因缺乏SessionId而使得服务器判定为一个新的会话,最终导致丢失了之前会话的状态。
默认情况下会回收无 cookie 会话中使用的会话 ID 值。即如果使用已过期的会话 ID 发起一个请求,将使用此请求提供的 SessionID 启动一个新的会话。将 sessionState 配置元素的 regenerateExpiredSessionId 属性设置为 true。这样,在使用已过期的会话 ID 发起无 cookie 会话请求时,将生成一个新的会话 ID。如果使用 HTTP POST 方法发起使用已过期会话 ID 的请求,则当 regenerateExpiredSessionId 为 true 时,将丢失发送的所有数据,因为 ASP.NET 会执行重定向,以确保浏览器在 URL 中具有新的会话标识符。但对于现在的Web系统而言会话过期都会导致请求时认证失败,重定向到登录页面,此时肯定会丢失所有提交的数据。
Session模式
ASP.NET 会话状态支持若干用于会话数据的存储选项。其通过web.config/sessionState中的mode属性设置,包含InProc(进程内),StateServer(状态服务器),SQLServer(SQL Server数据库模式),Custom(自定义模式),Off(禁用)
进程内模式:进程内模式是默认的会话状态模式,进程内模式将会话状态值和变量存储在本地 Web 服务器上的内存中。个人估计它是存储在工作进程(w3wp.exe)内。它是唯一支持 Session_OnEnd 事件的模式。
1.状态服务器模式:StateServer 模式将会话状态存储在一个称为 ASP.NET 状态服务的进程中,该进程是独立于 ASP.NET 辅助进程或 IIS 应用程序池的单独进程。使用此模式可以确保在重新启动 Web 应用程序时保留会话状态,并使会话状态可用于网络场中的多个 Web 服务器。
若要使用 StateServer 模式,必须首先确保 ASP.NET 状态服务运行在用于存储会话的服务器上。ASP.NET 状态服务在安装 ASP.NET 和 .NET Framework 时作为一个服务进行安装。ASP.NET 状态服务安装在以下位置:
比如我系统的.NET Framework4的状态服务在
stateConnectionString 属性设置为 tcpip=服务器名称:42424。
2.SQL Server模式:SQLServer 模式将会话状态存储到一个 SQL Server 数据库中。使用此模式可以确保在重新启动 Web 应用程序时保留会话状态,并使会话状态可用于网络场中的多个 Web 服务器。
若要将某个 ASP.NET 应用程序配置为使用 SQLServer 模式,请在该应用程序的 Web.config 文件中执行以下操作:
在命令提示符中输入以下命令
效果如下图所示
完成后发现数据库中有一个ASPState的数据库,包含表两张和若干个存储过程
用于存储session值的表示ASPStateTempSessions,当我们访问一个页面打开一个会话的时候,就往里面写入了一条数据
个人估计字段[SessionItemShort]和[SessionItemLong]就是存储Session值
3.自定义模式:Custom 模式指定您希望使用自定义会话状态存储提供程序来存储会话状态数据。在使用 Custom 的 Mode 配置 ASP.NET 应用程序时,必须使用 sessionState 配置元素的 providers 子元素指定会话状态存储提供程序的类型。使用 add 子元素来指定提供程序类型,并包括指定提供程序类型名称的 type 属性以及指定提供程序实例名称的 name 属性。然后,将提供程序实例的名称提供给 sessionState 元素的 customProvider 属性,将 ASP.NET 会话状态配置为使用该提供程序实例来存储和检索会话数据。具体实现的话可以参考两个地方查看《会话状态存储提供程序示例 》和《如何:演示会话状态存储提供程序》
Session事件
Session事件有两个:Session_OnStart 事件和 Session_OnEnd 事件;前者在新会话开始时引发,后者在会话被放弃或过期时引发。如需使用则定义在全局文件Global.asax里面则可,但是Session_OnEnd 事件只有在会话模式是InProc,也就是使用进程内模式。
后记
最后粘贴一下整个sessionState的配置节