ASP.NET 会话状态允许你为用户在不同的 ASP.NET 页面导航之间存储并获取状态值。因为 HTTP 是无状态的协议,所以这意谓着 Web 服务器会把页面的每个 HTTP 请求都视为是相对独立的;默认时,服务器在先前的请求期间并不知道变量的值。ASP.NET 会话状态会在一个有限的时间段期间(如会话过程)从相同浏览器中对被接收的请求进行识别,并为该会话在持续期间提供持续保持变量值的能力。
ASP.NET 会话状态在默认的时候是为所有 ASP.NET 应用程序所启用的。
相对于会话状态的另一种选择是应用程序状态(请参考:[Application
类]的属性),应用程序状态所存储的变量能够被 ASP.NET 应用程序的所有用户所访问;System.Web.Profile
命名空间在数据存储中持续保持用户的值,并确保这些值始终不会过期;System.Web.Caching
命名空间存储了经常在内存中被使用并且对于所有 ASP.NET 应用程序都可用的值;ASP.NET System.Web.UI.WebControls
命名空间会把控件的值持续保持到 ViewState
、Cookies
、QueryString
、以及 HTML 窗体的字符中,并在使用 Form
集合所发送的 HTTP POST 命令中可用。关于不同的状态管理选项之间的比较,请参考:[ASP.NET 状态管理的建议]。
会话变量
会话变量被存储在 System.Web.HttpContext.Session
属性所暴露的 SessionStateItemCollection
属性中。会话变量集合既能够使用变量的名称来做为索引也能够使用整数做索引。已创建的会话变量可以通过名称来进行简单的引用。并且你不需要声明一个会话变量或明确地把它添加到集合中。例如,如下代码实例为用户的姓名创建了一个会话变量,并且设置它们从 TextBox
控件中获取值。
Session["FirstName"] = FirstNameTextBox.Text; Session["LastName"] = LastNameTextBox.Text;
默认时,会话变量能够是任何有效的 .NET 类型。例如,如下代码实例把一个 ArrayList
存储为一个被称作 StockPicks 的会话变量的值。注意由 StockPicks 会话变量所返回的值必须在从 SessionStateItemCollection
集合中被获取之前转换成适当的类型。
提示:如果你在会话中使用了除 InProc
之外的状态模式,那么会话变量类型既可以是一个原始的 .NET 类型也可以进行序列化,这是因为会话变量的值是被存储在另外一个外部数据存储中的。关于更多信息,请参考:[会话的状态模式]。
// 在从会话状态中获取对象的时候,应该把它转换成适当的类型。 ArrayList stockPicks = (ArrayList)Session["StockPicks"]; // 把被更改的股票精选列表写回到会话状态中。 Session["StockPicks"] = stockPicks;
会话的标识符
会话通过在 SessionID
属性中使用一个唯一的会话标识符来进行识别。在 ASP.NET 应用程序启用了会话状态的时候,应用程序中的每个页面请求都会检查由浏览器所发送的 SessionID
的值。如果没有提供 SessionID
的值,ASP.NET 就会启动一个新的会话,并且该会话的 SessionID
被发送到请求来源的浏览器中。
默认时,SessionID
的值被存储在 Cookie 中,但是你同样能够配置你的应用程序为无 Cookie 会话而把 SessionID
的值存储到 URL 中。关于更多信息,请参考:[会话的标识符]。
会话在使用相同的 SessionID
值连续产生请求的时候被认为是活动的。如果特定会话请求之间的时间超出了被指定的时间上限(以分钟为单位),那么这个会话将被认为是已过期的。使用已过期的 SessionID
值所产生的页面请求会导致一个新的会话被启动。
会话的事件
ASP.NET 提供了两个事件来帮助你对用户会话进行管理:Session_Start
事件,在新的会话开始的时候被引发,还有 Session_OnEnd
事件,在会话被放弃或失效的时候被引发。ASP.NET 应用程序的会话事件在 Global.asax 文件中被指定。注意在会话的 Mode
属性被设置成除 InProc
之外的值的时候,Session_OnEnd
事件是不被支持的,而 InProc
是默认的会话模式。
提示:如果 ASP.NET 应用程序的 Global.asax 文件或 Web.config 文件被更改,那么应用程序将被重启,并且被存储在应用程序状态中或会话状态中的任何值都将被丢失。你应该了解到一些反病毒软件能够更新应用程序中 Global.asax 或 Web.config 文件的最后更新日期和时间,从而采取相应的措施。
关于更多信息,请参考:[会话状态的事件]。
会话的模式
ASP.NET 会话状态支持几个不同的会话变量存储选项。每个选项都被会话状态的 Mode
属性所标识。而默认的行为则是把会话变量存储到 ASP.NET 工作者进程的内存空间中。但是,你同样能够指定会话状态被存储到分离的进程中、SQL Server 数据库中、或者是自定义数据源中。如果你不需要在应用程序中启用会话状态,你可以把会话的模式设置成为 Off
。
关于更多信息,请参考:[会话状态的模式]。
配置会话状态
会话状态可以使用 system.web
配置段中的 sessionState
元素进行配置。你同样能够使用 EnableSessionState
页面指令来配置会话状态。
sessionState
元素允许你指定将要存储数据的会话的模式、会话标识符的值在客户端和服务器之间被发送的方式、会话的超时(Timout
属性)、以及基于会话模式(Mode
属性)所支持的值。例如,如下所示的 sessionState
元素为某个应用程序把会话模式配置成了 SQLServer
,还设置了超时(Timeout
属性)限制为 30 分钟,并指定会话的标签符是被存储在 URL 中的。
<sessionState mode="SQLServer" cookieless="true " regenerateExpiredSessionId="true " timeout="30" sqlConnectionString="Data Source=MySqlServer;Integrated Security=SSPI;" stateNetworkTimeout="30"/>
你能够把会话状态设置成 Off
来禁用应用程序的会话状态。如果你只需要禁用特定页面中的会话状态,你可以把 EnableSessionState
页面指令设置为 false
。注意 EnableSessionState
页面指令同样能够被设置成 ReadOnly
来为会话变量提供只读访问。
并发的请求和会话状态
ASP.NET 会话状态只能够由当前会话进行唯一的访问,这意谓着如果两个不同的用户产生了并发的请求,那么将并发产生两个分离的会话。但是,如果是相同的会话(也就是说,使用了相同 SessionID
值的会话)产生了两个并发的请求,那么第一个请求将被先允许能够对会话信息进行唯一的访问,而第二个请求则在第一个请求完成之后,或者在对信息的唯一锁定被第一个请求由于锁定超时而释放的时候才能够得以执行。如果 EnableSessionState
页面指令被设置成 ReadOnly
,那么针对只读会话信息所产生的请求就不会导致会话数据的唯一锁定。会话数据的只读请求可能还需要等待用于清理会话数据的读写请求取消对会话数据的锁定。