您的位置:首页 > 编程语言 > ASP

在asp.net中实现会话状态基础

2008-01-04 11:59 381 查看
您可以通过 sqlConnectionString 特性指定连接字符串。请注意,特性字符串必须包含用户 ID、密码和服务器名称。它不能包含
Database 和 Initial Catalog 之类的标记,因为此信息默认为固定名称。用户 ID 和密码可以替换为集成的安全设置。

如何创建数据库?ASP.NET 提供两对脚本来配置数据库环境。第一对脚本名为 InstallSqlState.sql 和
UninstallSqlState.sql,与会话状态 NT 服务位于同一个文件夹中。它们创建名为 ASPState
的数据库和几个存储的过程。但是,数据存储在 SQL Server 临时存储区域 TempDB 数据库中。这意味着,如果重新启动 SQL
Server 计算机,会话数据将丢失。

  要解决这一局限性,请使用第二对脚本。第二对脚本名为
InstallPersistSqlState.sql 和 UninstallPersistSqlState.sql。在这种情况下,将创建
ASPState 数据库,但是会在同一个数据库中创建数据表,而且这些数据表同样是持久的。为会话安装 SQL Server
支持时,还将创建一个作业,以删除会话状态数据库中过期的会话。该作业名为 ASPState_Job_DeleteExpiredSessions
并且一直运行。请注意,要使该作业正常进行,需要运行 SQLServerAgent 服务。

  无论您选择哪种模式,为会话状态操作进行编码的方式都不会改变。您可以始终针对 Session 属性进行工作并像平常一样读取和写入值。所有行为上的差异都是在较低的抽象层上处理的。状态序列化或许是会话模式之间的最重要差异。

  状态序列化和反序列化

使用进程内模式时,对象作为各自类的活动实例存储在会话状态中。如果未发生真正的序列化和反序列化,则表示您实际上可以在 Session
中存储您创建的任何对象(包括无法序列化的对象和 COM 对象),并且访问它们的开销也不会太高。如果您选择进程外状态提供程序,又是另外一种情况。

  在进程外体系结构中,会话值将从本地存储介质(外部 AppDomain 数据库)复制到处理请求的
AppDomain
的内存中。需要使用序列化/反序列化图层完成该任务,并表示进程外状态提供程序的某项主要成本。这种情况对代码产生的主要影响是只能在会话词典中存储可序
列化的对象。

  根据所涉及的数据类型,ASP.NET
使用两种方法对数据进行序列化和反序列化。对于基本类型,ASP.NET
使用经过优化的内部序列化程序;对于其他类型(包括对象和用户定义的类),ASP.NET 使用 .NET
二进制格式化程序。基本类型包括字符串、日期时间、布尔值、字节、字符以及所有的数字类型。对于这些类型,使用量身制作的序列化程序要比使用默认的常用
.NET 二进制格式化程序更快。

  经过优化的序列化程序没有公开发布,也没有以文档形式提供。它仅仅是
二进制读取器/写入器,并且使用简单但有效的存储架构。该序列化程序使用 BinaryWriter
类写入一个字节表示类型,然后写入一个字节表示该类型对应的值。读取序列化的字节时,该类首先提取一个字节,检测要读取的数据类型,然后对
BinaryReader 类调用特定类型的 ReadXxx 方法。

  请注意,布尔值和数字类型的大小
是众所周知的,但对字符串并非如此。在基础数据流上,字符串始终带有一个固定长度的前缀(一次编写 7
位整数代码),读取器根据这一事实来确定字符串的正确大小。而日期值是通过只写入构成日期的标记总数来保存的。因此,要对会话执行序列化操作,日期应为
Int64 类型。

  只要将包含的类标记为可序列化的类,便可以使用 BinaryFormatter
类对更复杂的对象(以及自定义对象)执行序列化操作。所有非基本类型都采用相同的类型 ID
进行标识并与基本类型存储在同一个数据流中。总之,序列化操作会导致性能下降 15% 至
25%。但请注意,这是基于假定使用基本类型所进行的粗略估计。使用的类型越复杂,开销越大。

  如果不大
量使用基本类型,很难实现有效的会话数据存储。因此,至少在理论上,使用三个会话槽保存对象的三个不同的字符串属性要比对整个对象进行序列化好。但是,如
果要序列化的对象包含 100 个属性,那该怎么办呢?是要使用 100
个槽,还是只使用一个槽?在许多情况下,更好的方法是将复杂的类型转换为多个简单的类型。这种方法基于类型转换器。“类型转换器”是一种轻便的序列化程
序,它以字符串集合的形式返回类型的关键属性。类型转换器是使用特性与基类绑定在一起的外部类。由类型编写者决定保存哪些属性以及如何保存。类型转换器对
于 ViewState 存储也有帮助,它代表的是比二进制格式化程序更有效的会话存储方法。

  会话的生命周期

  关于 ASP.NET 会话管理,重要的一点是,仅当将第一个项目添加到内存词典中时,会话状态对象的生命周期才开始。仅在执行如下代码片断后,才可以认为 ASP.NET 会话开始。

Session["MySlot"] = "Some data";

  Session 词典通常包含 Object 类型,要向后读取数据,需要将返回的值转换为更具体的类型。

string data = (string) Session["MySlot"];

当页面将数据保存到 Session 中时,会将值加载到 HttpSessionState
类包含的特制的词典类中。完成当前处理的请求时,会将词典的内容加载到状态提供程序中。如果由于未通过编程方式将数据放入词典而导致会话状态为空,则不会
将数据序列化到存储介质中,而且更重要的是,不会在 ASP.NET Cache、SQL Server 或 NT
状态服务中创建槽来跟踪当前会话。这是出于性能方面的原因,但会对处理会话 ID 的方式产生重要影响:将为每个请求生成一个新的会话
ID,直到将某些数据存储到会话词典中。

  需要将会话状态与正在处理的请求连接时,HTTP 模块会检索会话 ID(如果它不是启动请求),并在配置的状态提供程序中寻找它。如果没有返回数据,HTTP 模块将为请求生成一个新的会话 ID。这可以很容易地通过以下页面进行测试:

<%@ Page Language="C#" Trace="true" %>;

</HTML>;

<body>;

<form runat="server">;

<ASP:button runat="server" text="Click" />;

</form>;

</body>;

</HTML>;

  无论何时单击该按钮并返回页面,都将生成新的会话 ID,同时记录跟踪信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: