asp.net中如何实现会话状态(3)
session_onend 事件标志着会话的结束,并用于执行终止该会话所需的所有清除代码。但请注意,只有 inproc 模式支持该事件,也就是说,只有将会话数据存储在 asp.net 辅助进程中时才支持该事件。对于要引发的 session_onend 事件来说,必须首先存在会话状态,这意味着必须在该会话状态中存储一些数据,并且必须至少完成一个请求。
在 inproc 模式下,作为项目添加到缓存中的会话状态被赋予一个可变过期时间策略。可变过期时间表示如果某个项目在一定时间内没有使用,将被删除。在此期间处理的任何请求的过期时间都将被重置。会话状态项目的时间间隔被设置为会话超时。用来重置会话状态过期时间的技术非常简单和直观:会话 http 模块只读取 asp.net cache 中存储的会话状态项目。如果知道 asp.net cache 对象的内部结构,该模块将进行计算以重新设置可变过期时间。因此,当缓存项目过期时,会话已超时。
过期的项目将自动从缓存中删除。状态会话模块作为此项目的过期时间策略的一部分,也代表了一个删除回调函数。缓存将自动调用删除函数,删除函数然后将引发 session_onend 事件。如果应用程序通过进程外组件来执行会话管理,则永远不会引发结束事件。
cookieless 会话
每个活动 asp.net 会话都是使用仅由 url 允许的字符组成的 120 位字符串标识的。会话 id 是使用随机数生成器 (rng) 加密提供程序生成的。该服务提供程序返回一个包含 15 个随机生成数的序列(15 字节 x 8 位 = 120 位)。随机数数组然后被映射到有效的 url 字符并以字符串形式返回。
会话 id 字符串被发送到浏览器,然后通过以下两种方式之一返回服务器应用程序:使用 cookie(就像在传统 asp 中一样)或经过修改的 url。默认情况下,会话状态模块将在客户端创建 http cookie,但是可以使用嵌入会话 id 字符串的修改后的 url(特别是对于不支持 cookie 的浏览器)。采用哪种方法取决于应用程序的 web.config 文件中所存储的配置设置。要配置会话设置,可以使用 <sessionstate>; 区段和 cookieless 特性。
<sessionstate cookieless="true|false" />;
默认情况下,cookieless 特性为 false,表示使用了 cookie。实际上,cookie 只是 web 页放在客户端硬盘上的一个文本文件。在 asp.net 中,cookie 由 httpcookie 类的一个实例来表示。通常,cookie 包含名称、值集合和过期时间。cookieless 特性被设置为 false 时,会话状态模块实际上将创建一个名为 asp.net_sessionid 的 cookie 并将会话 id 存储在其中。下面的伪代码显示了创建 cookie 的过程:
httpcookie sessioncookie;
sessioncookie = new httpcookie("asp.net_sessionid", sessionid);
sessioncookie.path = "/";
会话 cookie 的过期时间很短,在每个请求成功后更新过期时间。cookie 的 expires 属性表示 cookie 在客户端的过期时间。如果未显式设置会话 cookie,expires 属性将默认为 datetime.minvalue,即 .net framework 允许的最小时间单位。
要禁用会话 cookie,请在配置文件中将 cookieless 特性设置为 true,如下所示:
<configuration>;
<system.web>;
<sessionstate cookieless="true" />;
</system.web>;
</configuration>;
此时,假设您请求以下 url 处的页面:
http://www.contoso.com/sample.aspx
浏览器地址栏中实际显示的内容会有所不同,现在包含会话 id,如下所示:
http://www.contoso.com/(5ylg0455mrvws1uz5mmaau45)/sample.aspx
实例化会话状态 http 模块时,该模块将检查 cookieless 特性的值。如果为 true,则将请求重定向 (http 302) 到经过修改的包含会话 id(紧跟在页面名称前)的虚拟 url。再次处理请求时,请求中会包含该会话 id。如果请求启动新的会话,http 模块将生成新的会话 id,然后重定向该请求。如果回传请求,则会话 id 已经存在,因为回传使用相对 url。
使用 cookieless 会话的缺点是,如果调用绝对 url,将丢失会话状态。使用 cookie 时,您可以清除地址栏,转至其他应用程序,然后返回上一个应用程序并检索相同的会话值。如果在禁用会话 cookie 时执行此操作,将丢失会话数据。例如,以下代码将打断该会话:[www.iocblog.net 来源]
<a runat="server" href="/code/page.aspx">;click</a>;
如果需要使用绝对 url,请通过一些小技巧手动将会话 id 添加到 url 中。您可以对 httpresponse 类调用 applyapppathmodifier 方法。
<a runat="server"
href=<% =response.applyapppathmodifier("/code/page.aspx")%>; >;click</a>;
applyapppathmodifier 方法将使用表示 url 的字符串,并返回嵌入会话信息的绝对 url。例如,需要从 http 页面重定向到 https 页面时,此技巧特别有用。
小结
会话状态最初由传统的 asp 引入,它是基于词典的 api,使开发人员能够存储会话期间的自定义数据。在 asp.net 中,会话状态支持以下两种主要功能:cookieless 会话 id 存储和传输,以及会话数据实际存储的状态提供程序。为实现这两种新功能,asp.net 利用 http 模块控制会话状态与正在处理的请求上下文之间的绑定。
在传统的 asp 中,使用会话状态就是指使用 cookie。在 asp.net 中已不再如此,因为可以使用 cookieless 架构。借助 http 模块的力量,可以分解请求的 url 以使其包含会话 id,然后将其重定向。接下来,http 模块会从该 url 中提取会话 id 并使用它检索任何存储的状态。
会话的物理状态可以存储在三个位置:进程内内存、进程外内存和 sql server 表。数据必须经过序列化/反序列化处理,才能供应用程序使用。http 模块会在请求开始时将会话值从提供程序复制到应用程序的内存中。请求完成后,修改后的状态将返回提供程序。这种数据通信会对性能产生不同程度的不利影响,但是会大大增强可靠性和稳定性,也使对 web farm 和 web garden 体系结构的支持更容易实现。
文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。