转自:http://www.cnblogs.com/aierong/archive/2008/12/01/Session.html
ASP.NET 允许您使用会话状态保存每个活动的 Web 应用程序会话的值,会话状态是 HttpSessionState 类的一个实例。
会话状态与应用程序状态相似,不同的只是会话状态的范围限于当前的浏览器会话。如果有不同的用户在使用您的应用程序,则每个用户会话都将有一个不同的会话状态。此外,如果同一用户在退出后又返回到应用程序,第二个用户会话的会话状态也会与第一个不同。
会话状态采用键/值字典形式的结构来存储特定于会话的信息,这些信息需要在服务器往返行程之间及页请求之间进行维护。
可以使用会话状态来完成以下任务:
1.唯一标识浏览器或客户端设备请求,并将这些请求映射到服务器上的单独会话实例。
2.在服务器上存储特定于会话的数据,以用于同一个会话内的多个浏览器或客户端设备请求。
3.引发适当的会话管理事件。此外,可以利用这些事件编写应用程序代码。
一旦将应用程序特定的信息添加到会话状态中,服务器就会管理该对象。根据您指定的选项的不同,可以将会话信息存储在 Cookie 中、进程外服务器中或运行 Microsoft SQL Server 的计算机中。
默认情况下,所有 ASP.NET 应用程序都启用 ASP.NET 会话状态。
会话变量
如何:保存会话状态中的值
会话变量存储在通过 System.Web.HttpContext.Session 属性公开的 SessionStateItemCollection 中。
会话变量集合按变量名称或整数索引来进行索引。仅需通过名称引用会话变量即可创建会话变量。无需声明会话变量或将会话变量显式添加到集合中。
例如,下面的代码示例创建分别表示用户的名字和姓氏的会话变量,并将它们设置为从 TextBox 控件检索到的值。
Session["FirstName"] = FirstNameTextBox.Text;
Session["LastName"] = LastNameTextBox.Text;
默认情况下,会话变量可以为任何有效的 .NET 类型。
例如,下面的代码示例将值的 ArrayList 存储在名为“StockPicks”的会话变量中。注意,由“StockPicks”会话变量返回的值在从 SessionStateItemCollection 检索出来时必须强制转换为适当的类型。
ArrayList stockPicks = (ArrayList)Session["StockPicks"];
Session["StockPicks"] = stockPicks;
如何:读取会话状态中的值
此示例访问 Item 属性来检索会话状态中的值。
string firstName = (string)(Session["First"]);
string lastName = (string)(Session["Last"]);
string city = (string)(Session["City"]);
如果尝试从不存在的会话状态中获取值,则不会引发任何异常。若要确保所需的值在会话状态中,请首先使用测试(例如以下测试)检查该对象是否存在:
if (Session["City"] == null)
// No such value in session state; take appropriate action.
会话标识符
浏览器的会话使用存储在 SessionID 属性中的唯一标识符进行标识。会话 ID 使 ASP.NET 应用程序能够将特定的浏览器与 Web 服务器上相关的会话数据和信息相关联。会话 ID 的值在浏览器和 Web 服务器间通过 Cookie 进行传输,如果指定了无 Cookie 会话,则通过 URL 进行传输。
无 Cookie SessionID
默认情况下,SessionID 存储在浏览器未到期会话的 Cookie 中。通过在 Web.config 文件的 sessionState 节中将 cookieless 属性设置为 TRUE,可以指定不将会话标识符存储在 Cookie 中。
ASP.NET 通过自动在页的 URL 中插入唯一的会话 ID 来保持无 Cookie 会话状态。
例如,下面的 URL 已被 ASP.NET 修改,以包含唯一的会话 ID lit3py55t21z5v55vlm25s55:
http://www.example.com/s(lit3py55t21z5v55vlm25s55)/orderform.aspx
ASP.NET 修改所有请求页中包含的使用相对于应用程序的路径的链接(不修改显式路径),方法是在将每页发送到浏览器之前,在链接中嵌入一个会话 ID 值。只要用户遵循 ASP.NET 应用程序提供的链接路径,即可保持会话状态。但是,如果客户端重写了应用程序提供的 URL,ASP.NET 将不能解析此会话 ID,也不能将此请求与现有的会话相关联,因此会为此请求启动一个新的会话。
会话 ID 嵌入在 URL 中应用程序名称后的斜杠之后,在其余所有文件或虚拟目录标识符之前。
会话状态事件
ASP.NET 提供了两种帮助您管理用户会话的事件:Session_OnStart 事件和 Session_OnEnd 事件;前者在新会话开始时引发,后者在会话被放弃或过期时引发。
Session_OnStart 事件
可以通过向 Global.asax 文件添加一个名为 Session_OnStart 的子例程来处理 Session_OnStart 事件。如果请求开始一个新会话,Session_OnStart 子例程会在请求开始时运行。如果请求不包含 SessionID 值或请求所包含的 SessionID 属性引用一个已过期的会话,则会开始一个新会话。
您可以使用 Session_OnStart 事件初始化会话变量并跟踪与会话相关的信息。
Session_OnEnd 事件
可以通过向 Global.asax 文件添加一个名为 Session_OnEnd 的子例程来处理 Session_OnEnd 事件。Session_OnEnd 子例程在 Abandon 方法已被调用或会话已过期时运行。如果超过了某一会话 Timeout 属性指定的分钟数并且在此期间内没有请求该会话,则该会话过期。
只有会话状态属性 Mode 设置为 InProc(默认值)时,才支持 Session_OnEnd 事件。如果会话状态属性 Mode 为 StateServer 或 SQLServer,则忽略 Global.asax 文件中的 Session_OnEnd 事件。如果会话状态属性 Mode 设置为 Custom,则由自定义会话状态存储提供程序决定是否支持 Session_OnEnd 事件。
您可以使用 Session_OnEnd 事件清除与会话相关的信息,如由 SessionID 值跟踪的数据源中的用户信息。
下面的代码示例演示一个可以添加到 Global.asax 文件的 Session_OnStart 和 Session_OnEnd 子例程示例。在此示例中定义的这些子例程创建一个计数器,用来跟踪正在使用应用程序的应用程序用户的数量。请注意,只有会话状态属性 Mode 设置为 InProc 时,此示例才会正常运行,因为只有进程内会话状态存储才支持 Session_OnEnd 事件。
<script language="C#" runat="server">
public void Application_OnStart()
{
Application["UsersOnline"] = 0;
}
public void Session_OnStart()
{
Application.Lock();
Application["UsersOnline"] = (int)Application["UsersOnline"] + 1;
Application.UnLock();
}
public void Session_OnEnd()
{
Application.Lock();
Application["UsersOnline"] = (int)Application["UsersOnline"] - 1;
Application.UnLock();
}
</script>
会话状态模式
ASP.NET 会话状态支持若干用于会话数据的存储选项。每个选项都由 SessionStateMode 枚举中的一个值标识。
下面的列表描述了可用的会话状态模式:
InProc 模式,此模式将会话状态存储在 Web 服务器上的内存中。这是默认设置。
StateServer 模式,此模式将会话状态存储在一个名为 ASP.NET 状态服务的单独进程中。这确保了在重新启动 Web 应用程序时会保留会话状态,并让会话状态可用于网络场中的多个 Web 服务器。
SQLServer 模式将会话状态存储到一个 SQL Server 数据库中。这确保了在重新启动 Web 应用程序时会保留会话状态,并让会话状态可用于网络场中的多个 Web 服务器。
Custom 模式,此模式允许您指定自定义存储提供程序。
Off 模式,此模式禁用会话状态。
通过在应用程序的 Web.config 文件中为 sessionState 元素的 mode 属性分配一个 SessionStateMode 枚举值,可以指定要让 ASP.NET 会话状态使用的模式。除了 InProc 和 Off 之外,其他模式都需要附加参数,例如将在本主题后面讨论的连接字符串值。通过访问 System.Web.SessionState.HttpSessionState.Mode 属性的值,可以查看当前选定的会话状态。
进程内模式
进程内模式是默认的会话状态模式,使用 InProcSessionStateMode 枚举值指定。进程内模式将会话状态值和变量存储在本地 Web 服务器上的内存中。它是唯一支持 Session_OnEnd 事件的模式。
状态服务器模式
StateServer 模式将会话状态存储在一个称为 ASP.NET 状态服务的进程中,该进程是独立于 ASP.NET 辅助进程或 IIS 应用程序池的单独进程。使用此模式可以确保在重新启动 Web 应用程序时保留会话状态,并使会话状态可用于网络场中的多个 Web 服务器。
SQL Server 模式
SQLServer 模式将会话状态存储到一个 SQL Server 数据库中。使用此模式可以确保在重新启动 Web 应用程序时保留会话状态,并使会话状态可用于网络场中的多个 Web 服务器。
自定义模式
Custom 模式指定您希望使用自定义会话状态存储提供程序来存储会话状态数据。在使用 Custom 的 Mode 配置 ASP.NET 应用程序时,必须使用 sessionState 配置元素的 providers 子元素指定会话状态存储提供程序的类型。使用 add 子元素来指定提供程序类型,并包括指定提供程序类型名称的 type 属性以及指定提供程序实例名称的 name 属性。然后,将提供程序实例的名称提供给 sessionState 元素的 customProvider 属性,将 ASP.NET 会话状态配置为使用该提供程序实例来存储和检索会话数据。
配置会话状态
使用 system.web 配置节的 sessionState 元素来配置会话状态。还可以使用 EnableSessionState 页指令来配置会话状态。
使用 sessionState 元素可以指定会话存储数据的模式、在客户端和服务器间发送会话标识符值的方式、会话 Timeout 值和基于会话 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,则对只读会话信息的请求不会导致对会话数据的独占锁定。可能仍需等到会话数据由读写请求而获得的锁定被解除后,对会话数据的只读请求才能得到满足。