ASP.NET默认情况下将会话信息存储在ASP.NET应用程序的内存空间【InPro】,存放在InPro中时,可能会出现会话信息丢失的情况,所以可以使用一个独立的服务存储会话信息以便重新启动ASP.NET应用程序后会话信息依然保留,将会话信息存储在StateServer或SQLServer中以便会话信息可供网络场中的多个Web服务器使用【重新启动ASP.NET应用程序后会话信息会保留】,或将会话信息存储在自定义数据存储区。
会话由一个可以使用SessionID属性读取的唯一会话标识符标识,为ASP.NET应用程序启用会话状态时,将检查应用程序中每个页面请求是否有浏览器发送的SessionID值,如果未提供任何SessionID值,则ASP.NET启动一个新会话,然后将该会话的SessionID随响应一起发送到浏览器
默认情况下,SessionID值存储在Cookie中,但也可以通过配置应用程序【在Web.config文件的SessionState节中将CookieLess属性设置为True】,将SessionID值存储在URL中。只要一直使用相同的SessionID值来发送请求,会话就被视为活动的,如果特定会话的请求发送时间超过指定的超时值,则该会话被视为过期,使用过期的SessionID值来发送请求将启动新会话。示意图:
注意:为提高应用程序的安全性,当用户从应用程序注销时,此时应用程序应当调用Abandon方法销毁Session。当在Web.config文件中进行如下配置时:
<sessionState mode="StateServer" cookieless="UseUri"></sessionState>
ASP.NET自动在页的URL中插入唯一的会话ID来保持无Cookie会话状态,如下所示:
将SessionState配置元素的regenerateExpiredSessionId属性设置为true,这样,在使用已过期的会话ID发起无Cookie会话请求时,将生成一个新的会话ID。
ASP.NET提供两个管理用户会话的事件:Session_OnStart和Session_OnEnd,如果将Mode设置为InProc以外的值,Session_OnEnd事件将不受支持
进程内模式是默认的会话状态模式,使用 InProc SessionStateMode 枚举值指定。进程内模式将会话状态值和变量存储在本地 Web 服务器上的内存中。它是唯一支持 Session_OnEnd 事件的模式。
StateServer模式将会话状态存储在一个称为ASP.NET状态服务【ASP.NET State Service】的进程中,该进程独立于ASP.NET辅助进程或IIS的单独进程。使用此模式可以确保在重新启动Web应用程序是保留会话状态,并使会话状态可用于网络场中的多个Web服务器。
若要将某个ASP.NET应用程序配置为使用StateServer模式,在Web.Config文件中将SessionState元素的Mode属性设置为StateServer,将stateConnectionString属性设置为tcpip=服务器名称:42424
<sessionState mode="StateServer" cookieless="UseUri" stateConnectionString="tcpip=118.114.21.5:42424" timeout="20"></sessionState>
运行程序出现如下错误:
解决方法:开启ASP.NET State Service:
更改注册表AllowRemoteConnection为1:
备注:如果Mode取值为StateServer或SQLServer,则存储在会话状态中的对象必须可序列化
SQLServer模式将会话状态存储到一个SQL Server数据库中,使用此模式可以确保在重新启动Web应用程序是保留会话状态,并使会话状态可用于网络场中的多个Web服务器。
若要使某个ASP.NET应用程序配置为使用SQL Server模式,将mode属性设置为SQLServer,将sqlConnectionString属性设置为SQL Server数据库的连接字符串,并且必须安装ASP.NET会话数据库,可以通过利用Aspnet_regsql.exe进行安装,Aspnet_regesql.exe路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319,运行Aspnet_regesql.exe安装SQLServer会话数据库:
Web.config配置:
<sessionState mode="SQLServer" cookieless="UseUri" sqlConnectionString="Data Source=LBWIN7;Initial Catalog=aspnetdb;Integrated Security=True" timeout="20"></sessionState>
<sessionState mode="[Off|InProc|StateServer|SQLServer|Custom]" timeout="number of minutes" cookieName="session identifier cookie name" cookieless="[true|false|AutoDetect|UseCookies|UseUri|UseDeviceProfile]" regenerateExpiredSessionId="[True|False]" sqlConnectionString="sql connection string" sqlCommandTimeout="number of seconds" allowCustomSqlDatabase="[True|False]" useHostingIdentity="[True|False]" stateConnectionString="tcpip=server:port" stateNetworkTimeout="number of seconds" customProvider="custom provider name"> <providers>...</providers> </sessionState>
默认配置:
<sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" stateNetworkTimeout="10" sqlConnectionString="data source=127.0.0.1;Integrated Security=SSPI" sqlCommandTimeout="30" customProvider="" cookieless="UseCookies" cookieName="ASP.NET_SessionId" timeout="20" allowCustomSqlDatabase="false" regenerateExpiredSessionId="true" partitionResolverType="" useHostingIdentity="true"> <providers> <clear /> </providers> </sessionState>