ASP.NET 状态管理概述
每次将网页发送到服务器时,都会创建网页类的一个新实例。在传统的 Web 编程中,这通常意味着在每一次往返行程中,与该页及该页上的控件相关联的所有信息都会丢失。例如,如果用户将信息输入到文本框,该信息将在从浏览器或客户端设备到服务器的往返行程中丢失。
为了解决传统的 Web 编程的固有限制,ASP.NET 包括了几个选项,可帮助您按页保留数据和在整个应用程序范围内保留数据。这些功能如下所示:
-
视图状态
-
控件状态
-
隐藏域
-
Cookie
-
查询字符串
-
应用程序状态
-
会话状态
-
配置文件属性
视图状态、控件状态、隐藏域、Cookie 和查询字符串均会涉及以不同方式将数据存储到客户端上。而应用程序状态、会话状态和配置文件属性都将数据存储到服务器上的内存中。每个选项都有不同的优点和缺点,具体取决于相应的方案。
基于客户端的状态管理选项
下面各节描述一些状态管理选项,这些选项涉及在页中或客户端计算机上存储信息。对于这些选项,在各往返行程间不会在服务器上维护任何信息。
视图状态
ViewState 属性提供一个字典对象,用于在对同一页的多个请求之间保留值。这是页用来在往返行程之间保留页和控件属性值的默认方法。
在处理页时,页和控件的当前状态会散列为一个字符串,并在页中保存为一个隐藏域或多个隐藏域(如果存储在 ViewState 属性中的数据量超过了 MaxPageStateFieldLength 属性中的指定值)。当将页回发到服务器时,页会在页初始化阶段分析视图状态字符串,并还原页中的属性信息。
也可以使用视图状态来存储值。有关详细信息,请参见如何:保存视图状态中的值。有关何时应使用视图状态的建议,请参见 ASP.NET 状态管理建议。
控件状态
有时,为了让控件正常工作,您需要按顺序存储控件状态数据。例如,如果编写了一个自定义控件,其中使用了不同的选项卡来显示不同的信息。为了让自定义控件按预期的方式工作,该控件需要知道在往返行程之间选择了哪个选项卡。可以使用 ViewState 属性来实现这一目的,不过,开发人员可以在页级别关闭视图状态,从而使控件无法正常工作。为了解决此问题,ASP.NET 页框架在 ASP.NET 中公开了一项名为控件状态的功能。
ControlState 属性允许您保持特定于某个控件的属性信息,且不能像 ViewState 属性那样被关闭。
隐藏域
ASP.NET 允许您将信息存储在 HiddenField 控件中,此控件将呈现为一个标准的 HTML 隐藏域。隐藏域在浏览器中不以可见的形式呈现,但您可以就像对待标准控件一样设置其属性。当向服务器提交页时,隐藏域的内容将在 HTTP 窗体集合中随同其他控件的值一起发送。隐藏域可用作一个储存库,您可以将希望直接存储在页中的任何特定于页的信息放置到其中。
![]() |
---|
恶意用户可以很容易地查看和修改隐藏域的内容。请不要在隐藏域中存储任何敏感信息或保障应用程序正确运行的信息。有关更多信息,请参见 ASP.NET 状态管理建议。 |
HiddenField 控件在其 Value 属性中只存储一个变量,并且必须通过显式方式添加到页上。有关更多信息,请参见 HiddenField Web 服务器控件概述。
为了在页处理期间能够使用隐藏域的值,必须使用 HTTP POST 命令提交相应的页。如果在您使用隐藏域的同时,为了响应某个链接或 HTTP GET 命令而对页进行了相应处理,那么隐藏域将不可用。有关推荐的使用方法,请参见 ASP.NET 状态管理建议。
Cookie
Cookie 是一些少量的数据,这些数据或者存储在客户端文件系统的文本文件中,或者存储在客户端浏览器会话的内存中。Cookie 包含特定于站点的信息,这些信息是随页输出一起由服务器发送到客户端的。Cookie 可以是临时的(具有特定的过期时间和日期),也可以是永久的。
可以使用 Cookie 来存储有关特定客户端、会话或应用程序的信息。Cookie 保存在客户端设备上,当浏览器请求某页时,客户端会将 Cookie 中的信息连同请求信息一起发送。服务器可以读取 Cookie 并提取它的值。一项常见的用途是存储标记(可能已加密),以指示该用户已经在您的应用程序中进行了身份验证。
![]() |
---|
浏览器只能将数据发送回最初创建该 Cookie 的服务器。但是,恶意用户可通过多种方法访问 Cookie 并读取其中的内容。建议您不要将敏感信息(如用户名或密码)存储在 Cookie 中。您可以在 Cookie 中存储一个标识用户的标记,然后使用该标记在服务器上查找敏感信息。 |
有关使用 Cookie 的更多信息,请参见 Cookies 和 ASP.NET 状态管理建议。
查询字符串
查询字符串是在页 URL 的结尾附加的信息。下面是一个典型的查询字符串示例:
http://www.contoso.com/listwidgets.aspx?category=basic&price=100
在上面的 URL 路径中,查询字符串以问号 (?) 开始,并包含两个属性/值对:一个名为“category”,另一个名为“price”。
查询字符串提供了一种维护状态信息的方法,这种方法很简单,但有使用上的限制。例如,利用查询字符串可以很容易地将信息从一页传送到另一页。例如,将产品号从一页传送到将处理该产品号的另一页。但是,大多数浏览器和客户端设备会将 URL 的最大长度限制为 2083 个字符。
![]() |
---|
在查询字符串中传递的信息可能会被恶意用户篡改。不要依靠查询字符串来传递重要的或敏感的数据。此外,用户可以创建 URL 的书签或将 URL 发送给其他用户,从而将这些信息与 URL 一起传递。有关更多信息,请参见 ASP.NET 状态管理建议和如何:通过对字符串应用 HTML 编码在 Web 应用程序中防止脚本侵入。 |
若要在页处理期间可以使用查询字符串的值,必须使用 HTTP GET 命令提交页。也就是说,如果为了响应 HTTP POST 命令而对页进行了相应处理,则不能利用查询字符串。有关推荐的使用方法,请参见 ASP.NET 状态管理建议。
基于服务器的状态管理选项
ASP.NET 为您提供了多种方法,用于维护服务器上的状态信息,而不是保持客户端上的信息。通过基于服务器的状态管理,为了保留状态,您可以减少发送给客户端的信息量,但它可能会使用服务器上高成本的资源。下面各节描述了三种基于服务器的状态管理功能:应用程序状态、会话状态及配置文件属性。
应用程序状态
ASP.NET 允许您使用应用程序状态来保存每个活动的 Web 应用程序的值,应用程序状态是 HttpApplicationState 类的一个实例。应用程序状态是一种全局存储机制,可从 Web 应用程序中的所有页面访问。因此,应用程序状态可用于存储需要在服务器往返行程之间及页请求之间维护的信息。有关更多信息,请参见 ASP.NET 应用程序状态概述。
应用程序状态存储在一个键/值字典中,在每次请求一个特定的 URL 期间就会创建这样一个字典。可以将特定于应用程序的信息添加到此结构以在页请求期间存储它。
一旦将应用程序特定的信息添加到应用程序状态中,服务器就会管理该对象。有关推荐的使用方法,请参见 ASP.NET 状态管理建议。
会话状态
ASP.NET 允许您使用会话状态保存每个活动的 Web 应用程序会话的值,会话状态是 HttpSessionState 类的一个实例。有关概述,请参见会话状态概述。
会话状态与应用程序状态相似,不同的只是会话状态的范围限于当前的浏览器会话。如果有不同的用户在使用您的应用程序,则每个用户会话都将有一个不同的会话状态。此外,如果同一用户在退出后又返回到应用程序,第二个用户会话的会话状态也会与第一个不同。
会话状态采用键/值字典形式的结构来存储特定于会话的信息,这些信息需要在服务器往返行程之间及页请求之间进行维护。有关更多信息,请参见会话状态概述。
可以使用会话状态来完成以下任务:
-
唯一标识浏览器或客户端设备请求,并将这些请求映射到服务器上的单独会话实例。
-
在服务器上存储特定于会话的数据,以用于同一个会话内的多个浏览器或客户端设备请求。
-
引发适当的会话管理事件。此外,可以利用这些事件编写应用程序代码。
一旦将应用程序特定的信息添加到会话状态中,服务器就会管理该对象。根据您指定的选项的不同,可以将会话信息存储在 Cookie 中、进程外服务器中或运行 Microsoft SQL Server 的计算机中。有关推荐的使用方法,请参见 ASP.NET 状态管理建议。
配置文件属性
ASP.NET 提供了一个称为配置文件属性的功能,可让您存储特定于用户的数据。此功能与会话状态类似,不同的是,在用户的会话过期时,配置文件数据不会丢失。配置文件属性功能使用 ASP.NET 配置文件,此配置文件以持久的格式存储,并与某个用户关联。ASP.NET 配置文件可让您轻松地管理用户信息,而无需创建和维护自己的数据库。此外,配置文件使用了一个强类型 API,您可以在应用程序中的任何位置访问该 API,从而使用用户信息。您可以在配置文件中存储任何类型的对象。ASP.NET 配置文件功能提供了一个通用存储系统,使您能够定义和维护几乎任何类型的数据,同时仍可用类型安全的方式使用数据。
若要使用配置文件属性,必须对配置文件提供程序进行配置。ASP.NET 包括一个 SqlProfileProvider 类,使您能够将配置文件数据存储到 SQL 数据库中,但您也可以创建自己的配置文件提供程序类,用于以自定义格式将配置文件数据存储到自定义存储机制,如 XML 文件或 Web 服务。
因为放置在配置文件属性中的数据没有存储到应用程序内存中,所以这些数据在 Internet 信息服务 (IIS) 重新启动或辅助进程重新启动后仍能得到保留,而不会丢失。此外,配置文件属性可以跨多个进程得到保持,例如在网络场或网络园中。有关更多信息,请参见 ASP.NET 配置文件属性概述。
ASP.NET 2.0 版保留了 ASP.NET 1.1 版的许多功能,包括使用视图状态的自动页面状态持久性和对会话和应用程序状态的数据库支持。另外,ASP.NET 2.0 添加了两个新功能:视图状态分块和控件状态。
控件状态
为了让控件正常工作,有时需要存储控件状态数据。例如,如果编写了一个自定义控件,其中具有显示不同信息的不同选项卡,为使该控件如预期一样工作,控件需要知道在往返过程中选择的是哪个选项卡。ViewState 属性可用于此目的,但开发人员可能在页级别关闭了视图状态,从而有效地中断控件。为解决此问题,ASP.NET 页框架在 ASP.NET 2.0 版中公开了一种称为控件状态的新功能。
ControlState 属性允许保持特定于控件的属性信息,不像 ViewState 属性一样可以关闭。若要使用控件状态,控件必须在初始化过程中调用 RegisterRequiresControlState 方法,然后重写 SaveControlState 和 LoadControlState 方法。
配置文件属性
很多时候您需要存储特定于用户的数据,以便对用户使用应用程序时的用户体验进行自定义。有两种主要的方法可以在 ASP.NET 1.1 中实现这一点。会话状态提供了一种简单的存储特定于用户的信息的方法。但是,当用户会话过期时,会话状态会从内存中移除。还可以使用 Cookie 来存储唯一用户标识符,然后保持和检索数据库中的信息。但是,这需要自定义代码。为解决此问题,ASP.NET 2.0 提供了一种称为配置文件属性的新功能,它允许存储特定于用户的数据。
配置文件属性功能与会话状态类似,区别在于用户会话过期时配置文件数据不会丢失。相反,配置文件属性功能使用以持久性格式存储且与单个用户关联的 ASP.NET 配置文件。ASP.NET 配置文件允许您在无需创建和维护自己的数据库的情况下管理用户信息。此外,配置文件使用了一个强类型 API,您可以在应用程序中的任何位置访问该 API,从而使用用户信息。您可以在配置文件中存储任何类型的对象。ASP.NET 配置文件功能提供了一个通用存储系统,使您能够定义和维护几乎任何类型的数据,同时仍可用类型安全的方式使用数据。
有关更多信息,请参见 ASP.NET 配置文件属性概述。
视图状态分块
视图状态提供了一种简单的方法来自动保持页上的字段和控件数据,而不需要在往返服务器期间手动请求并重新填充。它还允许在 ViewState 属性中存储页上的自定义数据。
但是,在某些情况下,视图状态数据会变得很大。因为视图数据存储在隐藏的字段中,某些代理或防火墙会阻止对包含这些数据的页的访问。因此,ASP.NET 2.0 页框架引入了一种名为视图状态分块的功能。如果视图状态的数据量变得太大,视图状态分块自动将数据分成多个块区,并将这些数据放在多个隐藏形式的字段中。
若要启用视图状态分块,请将 MaxPageStateFieldLength 属性设置为在单个视图状态字段中允许的最大大小(以字节为单位)。当该页回发到服务器时,该页会在页初始化阶段分析视图状态字符串,并还原页中的属性信息。默认设置是 -1,这表示不存在最大大小,不会将视图状态分成多个块区。
有关更多信息,请参见视图状态概述。
自定义会话状态管理
默认情况下,会话状态的值和信息存储在内存的 ASP.NET 进程中。ASP.NET 还提供会话状态提供程序,它允许您使用可在单独的进程中保留会话数据的会话状态服务器,或者您可以将会话状态数据保持在 SQL 数据库中。但是,对于 ASP.NET 2.0,您可以创建自定义会话状态提供程序,它允许您自定义会话状态数据在 ASP.NET 应用程序中的存储方式。例如,如果出现以下原因,就可以考虑创建一个自定义提供程序:
-
您需要在 SQL Server 外的其他数据源(如 Visual FoxPro 数据库或 Oracle 数据库)中存储会话状态信息。
-
需要使用不同于 .NET Framework 附带的提供程序所使用的数据库架构来管理会话状态信息。一个示例就是使用预定义架构存储在某个公司或网站的现有 SQL Server 数据库中的购物车数据。
有关更多信息,请参见实现会话状态存储提供程序。
HiddenField 控件
视图状态提供了在网页上存储数据的编程能力,它自动检索、保持和维护页上的隐藏形式字段中的数据。但是,ASP.NET 2.0 添加了一个新的 Web 控件,HiddenField 控件呈现为 input type="hidden"/ 元素,但提供了一个与其他 Web 控件一致的 API。
状态管理是您对同一页或不同页的多个请求维护状态和页信息的过程。与所有基于 HTTP 的技术一样,Web 窗体页是无状态的,这意味着它们不自动指示序列中的请求是否全部来自相同的客户端,或者单个浏览器实例是否一直在查看页或站点。此外,到服务器的每一往返过程都将销毁并重新创建页;因此,如果超出了单个页的生命周期,页信息将不存在。有关服务器往返过程和 Web 窗体页生命周期的更多信息,请参见 ASP.NET 页生命周期概述。
ASP.NET 提供多种方式来在服务器往返过程之间维护状态。对这些状态管理选项的选择主要取决于您的应用程序,并且应基于以下条件:
-
需要存储的信息量有多大?
-
客户端是接受持久性的还是内存中的 Cookie?
-
要将信息存储在客户端还是服务器上?
-
信息是否是敏感信息?
-
您对应用程序设定了什么样的性能和带宽条件?
-
目标浏览器和设备具有什么样的功能?
-
您是否需要储存基于用户的信息?
-
信息需要存储多长时间?
-
您使用 Web 场(多个服务器)、Web 园(一个计算机上的多个进程)还是单个进程来运行应用程序?
客户端状态管理选项
使用客户端选项存储页信息不使用服务器资源。这些选项往往具有最低的安全性但具有较快的服务器性能,因为对服务器资源的要求是适度的。但是,由于必须将信息发送到客户端来进行存储,因此对于以这种方式可以存储多少信息存在一定的客观限制。
以下是 ASP.NET 支持的客户端状态管理选项:
-
视图状态
-
控件状态
-
隐藏域
-
Cookie
-
查询字符串
视图状态
Web 窗体页提供 ViewState 属性作为内置结构,在对同一页的多个请求间自动保留值。视图状态作为页中的隐藏域来进行维护。有关更多信息,请参见 ASP.NET 状态管理概述。
可以使用视图状态在页回发到自身时跨越往返过程存储您自己的页特定值。例如,如果您的应用程序正在维护用户特定的信息(即,该信息在页上使用,但不是任何控件所必需的部分),则可以使用视图状态存储该信息。
使用视图状态的优点为:
-
不需要任何服务器资源 视图状态包含在页代码内的结构中。
-
实现简单 视图状态无需使用任何自定义编程。默认情况下对控件启用状态数据的维护。
-
增强的安全功能 视图状态中的值经过哈希计算和压缩,并且针对 Unicode 实现进行编码,其安全性要高于使用隐藏域。
使用视图状态的缺点为:
-
性能注意事项 由于视图状态存储在页本身,因此如果存储较大的值,用户显示页和发布页时的速度可能会减慢。尤其是对移动设备,其带宽通常是有限的。
-
设备限制 移动设备可能没有足够的内存容量来存储大量的视图状态数据。
-
潜在的安全风险 视图状态存储在页上的一个或多个隐藏域中。虽然视图状态以哈希格式存储数据,但它可以被篡改。如果直接查看页输出源,可以看到隐藏域中的信息,这导致潜在的安全性问题。有关更多信息,请参见 ASP.NET Web 应用程序安全性和 Web 应用程序的基本安全实施策略。
有关使用视图状态的更多信息,请参见视图状态概述。
控件状态
ASP.NET 页框架提供了 ControlState 属性作为在服务器往返过程中存储自定义控件数据的方法。例如,如果您编写的自定义控件使用多个不同的选项卡来显示不同的信息,为使此控件能够按预期方式工作,控件需要知道在往返过程中哪个选项卡被选中。视图状态可用于此目的,但是开发人员可能在页级将视图状态关闭,这实际上破坏了您的控件。与视图状态不同,控件状态不能被关闭,因此它提供了存储控件状态数据的更可靠方法。
使用控件状态的优点为:
-
不需要任何服务器资源 默认情况下,控件状态存储在页上的隐藏域中。
-
可靠性 因为控件状态不像视图状态那样可以关闭,控件状态是管理控件的状态的更可靠方法。
-
通用性 可以编写自定义适配器来控制如何存储控件状态数据和控件状态数据的存储位置。
使用控件状态的缺点为:
-
需要一些编程 虽然 ASP.NET 页框架为控件状态提供了基础,但是控件状态是一个自定义的状态保持机制。为了充分利用控件状态,您必须编写代码来保存和加载控件状态。
隐藏域
可以在页上的隐藏域中存储特定于页的信息,作为维护页的状态的一种方式。有关隐藏域的更多信息,请参见 ASP.NET 状态管理建议。
如果使用隐藏域,最好在客户端上只存储少量经常更改的数据。
![]() |
---|
如果使用隐藏域,则必须使用 HTTP POST 方法向服务器提交页,而不是使用通过页 URL 请求该页的方法(HTTP GET 方法)向服务器提交页。 |
使用隐藏域的优点为:
-
不需要任何服务器资源 隐藏域在页上存储和读取。
-
广泛的支持 几乎所有浏览器和客户端设备都支持具有隐藏域的窗体。
-
实现简单 隐藏域是标准的 HTML 控件,不需要复杂的编程逻辑。
使用隐藏域的缺点为:
-
潜在的安全风险 隐藏域可以被篡改。如果直接查看页输出源,可以看到隐藏域中的信息,这导致潜在的安全性问题。您可以手动加密和解密隐藏域的内容,但这需要额外的编码和开销。如果关注安全,请考虑使用基于服务器的状态机制,从而不将敏感信息发送到客户端。有关更多信息,请参见 ASP.NET Web 应用程序安全性和 Web 应用程序的基本安全实施策略。
-
简单的存储结构 隐藏域不支持复杂数据类型。隐藏域只提供一个字符串值域存放信息。若要存储多个值,必须实现分隔的字符串以及用来分析那些字符串的代码。您可以手动分别将复杂数据类型序列化为隐藏域以及将隐藏域反序列化为复杂数据类型。但是,这需要额外的代码来实现。如果您需要将复杂数据类型存储在客户端上,请考虑使用视图状态。视图状态内置了序列化,并且将数据存储在隐藏域中。
-
性能注意事项 由于隐藏域存储在页本身,因此如果存储较大的值,用户显示页和发布页时的速度可能会减慢。
-
存储限制 如果隐藏域中的数据量过大,某些代理和防火墙将阻止对包含这些数据的页的访问。因为最大数量会随所采用的防火墙和代理的不同而不同,较大的隐藏域可能会出现偶发性问题。如果您需要存储大量的数据项,请考虑执行下列操作之一:
-
将每个项放置在单独的隐藏域中。
-
使用视图状态并打开视图状态分块,这样会自动将数据分割到多个隐藏域。
-
不将数据存储在客户端上,将数据保留在服务器上。向客户端发送的数据越多,您的应用程序的表面响应时间越慢,因为浏览器需要下载或发送更多的数据。
-
Cookie
Cookie 用于在客户端上存储少量经常更改的信息。这些信息与请求一起发送到服务器。有关创建和读取 Cookie 的详细信息,请参见 ASP.NET Cookie 概述。
使用 Cookie 的优点为:
-
可配置到期规则 Cookie 可以在浏览器会话结束时到期,或者可以在客户端计算机上无限期存在,这取决于客户端的到期规则。
-
不需要任何服务器资源 Cookie 存储在客户端并在发送后由服务器读取。
-
简单性 Cookie 是一种基于文本的轻量结构,包含简单的键值对。
-
数据持久性 虽然客户端计算机上 Cookie 的持续时间取决于客户端上的 Cookie 过期处理和用户干预,Cookie 通常是客户端上持续时间最长的数据保留形式。
使用 Cookie 的缺点为:
-
大小受到限制 大多数浏览器对 Cookie 的大小有 4096 字节的限制,尽管在当今新的浏览器和客户端设备版本中,支持 8192 字节的 Cookie 大小已愈发常见。
-
用户配置为禁用 有些用户禁用了浏览器或客户端设备接收 Cookie 的能力,因此限制了这一功能。
-
潜在的安全风险 Cookie 可能会被篡改。用户可能会操纵其计算机上的 Cookie,这意味着会对安全性造成潜在风险或者导致依赖于 Cookie 的应用程序失败。另外,虽然 Cookie 只能被将它们发送到客户端的域访问,历史上黑客已经发现从用户计算机上的其他域访问 Cookie 的方法。您可以手动加密和解密 Cookie,但这需要额外的编码,并且因为加密和解密需要耗费一定的时间而影响应用程序的性能。有关更多信息,请参见 ASP.NET Web 应用程序安全性和 Web 应用程序的基本安全实施策略。
注意
Cookie 通常用于为已知用户自定义内容的个性化情况。在大多数此类情况中,Cookie 是作为“标识”而不是“身份验证”。因此,通常保护用于标识的 Cookie 的方法是在 Cookie 中存储用户名、帐户名或唯一用户 ID(例如 GUID),然后用以访问站点的用户个性化结构中的信息。
查询字符串
查询字符串是在页 URL 的结尾附加的信息。有关更多信息,请参见 ASP.NET 状态管理概述。
可以使用查询字符串来通过 URL 将数据提交回您的页或另一页上。查询字符串提供一种维护某些状态信息的简单但有限的方法。例如,它们是将信息从一页传送到另一页的简便的方法(例如,将产品号传递到将处理该产品号的另一页)。
使用查询字符串的优点为:
-
不需要任何服务器资源 查询字符串包含在对特定 URL 的 HTTP 请求中。
-
广泛的支持 几乎所有的浏览器和客户端设备均支持使用查询字符串传递值。
-
实现简单 ASP.NET 完全支持查询字符串方法,其中包含了使用 HttpRequest 对象的 Params 属性读取查询字符串的方法。
使用查询字符串的缺点为:
-
潜在的安全性风险 用户可以通过浏览器用户界面直接看到查询字符串中的信息。用户可将此 URL 设置为书签或发送给别的用户,从而通过此 URL 传递查询字符串中的信息。如果您担心查询字符串中的任何敏感数据,请考虑使用窗体(使用 POST 而不是查询字符串)中的隐藏域。有关更多信息,请参见 ASP.NET Web 应用程序安全性和 Web 应用程序的基本安全实施策略。
-
有限的容量 有些浏览器和客户端设备对 URL 的长度有 2083 个字符的限制。
客户端方法状态管理摘要
下表列出了 ASP.NET 可用的客户端状态管理选项,并提供了有关何时使用每个选项的建议。
状态管理选项 | 使用建议 | ||
---|---|---|---|
视图状态 | 当您需要存储少量回发到自身的页信息时使用。使用 ViewState 属性可提供具有基本安全性的功能。 | ||
控件状态 | 当您需要在服务器的往返过程间存储少量控件状态信息时使用。 | ||
隐藏域 | 当您需要存储少量回发到自身或另一页的页信息时使用,也可以在不存在安全性问题时使用。
| ||
Cookie | 当您需要在客户端存储少量信息以及不存在安全性问题时使用。 | ||
查询字符串 | 当您将少量信息从一页传输到另一页以及不存在安全性问题时使用。
|
服务器端状态管理选项
存储页信息的服务器端选项往往比客户端选项具有更高的安全性,但它们可能使用更多的 Web 服务器资源,这可能在信息存储量较大时导致伸缩性方面的问题。ASP.NET 提供几种选项来实现服务器端状态管理。有关更多信息,请参见 ASP.NET 状态管理概述。
以下是 ASP.NET 支持的服务器端状态管理选项:
-
应用程序状态
-
会话状态
-
配置文件属性
-
数据库支持
应用程序状态
ASP.NET 通过 HttpApplicationState 类将应用程序状态提供为一种存储全局应用程序特定信息(对于整个应用程序都可见)的方法。应用程序状态变量实际上是 ASP.NET 应用程序的全局变量。有关更多信息,请参见 ASP.NET 应用程序状态概述
您可以在应用程序状态中存储应用程序特定的值,应用程序状态将由服务器来管理。有关更多信息,请参见 ASP.NET 状态管理概述。
由多个会话共享并且不经常更改的数据是插入到应用程序状态变量的理想数据。
使用应用程序状态的优点为:
-
实现简单 应用程序状态易于使用,为 ASP 开发人员所熟悉,并且与其他 .NET Framework 类一致。
-
应用程序范围 由于应用程序状态可供应用程序中的所有页来访问,因此在应用程序状态中存储信息可能意味着仅保留信息的一个副本(例如,相对于在会话状态或在单独页中保存信息的多个副本)。
使用应用程序状态的缺点为:
-
应用程序范围 应用程序状态的范围可能也是一项缺点。在应用程序状态中存储的变量仅对于该应用程序正在其中运行的特定进程而言是全局的,并且每一应用程序进程可能具有不同的值。因此,不能依赖应用程序状态来存储唯一值或更新 Web 场和 Web 园服务器配置中的全局计数器。
-
数据持续性有限 因为在应用程序状态中存储的全局数据是易失的,所以如果包含这些数据的 Web 服务器进程被损坏(如因服务器崩溃、升级或关闭而损坏),将丢失这些数据。
-
资源要求 应用程序状态需要服务器内存,这可能会影响服务器的性能以及应用程序的可伸缩性。
应用程序状态的精心设计和实现可以提高 Web 应用程序性能。例如,如果将常用的、相关的静态数据集放置到应用程序状态中,则可以通过减少对数据库的数据请求总数来提高站点性能。但是,这里存在一种性能平衡。当服务器负载增加时,包含大块信息的应用程序状态变量就会降低 Web 服务器的性能。在移除或替换值之前,将不释放在应用程序状态中存储的变量所占用的内存。因此,最好只将应用程序状态变量用于更改不频繁的小型数据集。有关更多信息,请参见开发高性能的 ASP.NET 应用程序。
会话状态
ASP.NET 提供了一种会话状态,该会话状态可作为 HttpSessionState 类或存储会话特定信息(仅在该会话中可见)的方法来使用。ASP.NET 会话状态将一个有限时间窗口内来自同一浏览器的请求标识为一个会话,并在该会话持续期间保留变量的值。有关更多信息,请参见 ASP.NET 状态管理概述和会话状态概述。
可以在会话状态中存储会话特定的值和对象,该会话状态对象将由服务器来进行管理并可用于浏览器或客户端设备。存储在会话状态变量中的理想数据是特定于单独会话的短期的、敏感的数据。
使用会话状态的优点为:
-
实现简单 会话状态功能易于使用,为 ASP 开发人员所熟悉,并且与其他 .NET Framework 类一致。
-
会话特定的事件 会话管理事件可以由应用程序引发和使用。
-
数据持久性 放置于会话状态变量中的数据可以经受得住 Internet 信息服务 (IIS) 重新启动和辅助进程重新启动,而不丢失会话数据,这是因为这些数据存储在另一个进程空间中。此外,会话状态数据可跨多进程保持(例如在 Web 场或 Web 园中)。
-
平台可伸缩性 会话状态可在多计算机和多进程配置中使用,因而优化了可伸缩性方案。
-
无需 Cookie 支持 尽管会话状态最常见的用途是与 Cookie 一起向 Web 应用程序提供用户标识功能,但会话状态可用于不支持 HTTP Cookie 的浏览器。但是,使用无 Cookie 的会话状态需要将会话标识符放置在查询字符串中(同样会遇到本主题在查询字符串一节中陈述的安全问题)。有关使用无 Cookie 会话状态的更多信息,请参见配置 ASP.NET 应用程序。
-
可扩展性 您可通过编写自己的会话状态提供程序自定义和扩展会话状态。然后可以通过多种数据存储机制(例如数据库、XML 文件甚至 Web 服务)将会话状态数据以自定义数据格式存储。有关更多信息,请参见实现会话状态存储提供程序。
使用会话状态的缺点为:
-
性能注意事项 会话状态变量在被移除或替换前保留在内存中,因而可能降低服务器性能。如果会话状态变量包含诸如大型数据集之类的信息块,则可能会因服务器负荷的增加影响 Web 服务器的性能。
配置文件属性
ASP.NET 提供了一个称为配置文件属性的功能,可让您存储特定于用户的数据。除了当用户的会话过期时配置文件数据不丢失这点与会话状态不同外,它与会话状态类似。配置文件属性功能使用 ASP.NET 配置文件,ASP.NET 配置文件以固定的格式存储并与单个用户相关联。ASP.NET 配置文件可让您轻松地管理用户信息,而无需创建和维护自己的数据库。此外,配置文件使用了一个强类型 API,您可以在应用程序中的任何位置访问该 API,从而使用用户信息。您可以在配置文件中存储任何类型的对象。ASP.NET 配置文件功能提供了一个通用存储系统,使您能够定义和维护几乎任何类型的数据,同时仍可用类型安全的方式使用数据。有关更多信息,请参见 ASP.NET 配置文件属性概述。
使用配置文件属性的优点为:
-
数据持久性 放置在配置文件属性中的数据在 IIS 和辅助进程重新启动过程中得以保留而不会丢失数据,因为数据存储在一个外部机制中。此外,配置文件属性可跨多进程保持(例如在 Web 场或 Web 园中)。
-
平台可伸缩性 配置文件属性可在多计算机和多进程配置中使用,因而优化了可伸缩性方案。
-
可扩展性 为了使用配置文件属性,您必须对配置文件提供程序进行配置。ASP.NET 提供了一个 SqlProfileProvider 类,使您可以将配置文件数据存储在 SQL 数据库中,但您也可以创建自己的配置文件提供程序类将配置文件数据按自定义格式存储到自定义存储机制中,例如 XML 文件甚至 Web 服务。有关更多信息,请参见 ASP.NET 配置文件提供程序和实现配置文件提供程序。
使用配置文件属性的缺点为:
-
性能注意事项 配置文件属性通常比使用会话状态慢,因为前者将数据持久保存到数据存储设备而非内存中。
-
额外的配置要求 与会话状态不同,配置文件属性功能需要使用相当数量的配置。若要使用配置文件属性,您不仅要对配置文件提供程序进行配置,还要预先配置您想要存储的所有配置文件属性。有关更多信息,请参见 ASP.NET 配置文件属性概述和定义 ASP.NET 配置文件属性。
-
数据维护 配置文件属性需要一定的维护。因为配置文件数据持久保存到存储设备中,所以必须确保在数据陈旧时,应用程序调用由配置文件提供程序提供的相应清理机制。
数据库支持
在某些情况中,您可能希望使用数据库支持来维护网站上的状态。通常,数据库支持与 Cookie 或会话状态结合在一起使用。例如,对于电子商务网站,普遍使用关系数据库维护状态信息,其原因是:
-
安全性
-
个性化
-
一致性
-
数据挖掘
下面是支持 Cookie 的数据库网站的常见功能:
-
安全性 访问者将帐户名称和密码键入到站点登录页中。站点结构通过登录值查询数据库以确定该用户是否有权使用您的站点。如果数据库确认该用户信息有效,网站将把包含该用户的唯一 ID 的有效 Cookie 分发到客户端计算机上。站点授予该用户访问权限。
-
个性化 通过站点中存储的安全性信息,您的站点能够借助读取客户端计算机上的 Cookie 来区分站点上的每一用户。通常,站点在数据库中具有信息,描述用户的首选项(由唯一 ID 标识)。此关系通称作个性化。站点可以使用在 Cookie 中包含的唯一 ID 获知用户的首选项,然后向用户提供与用户的特定愿望相关并在一段时间内对用户首选项作出反应的内容和信息。
-
一致性 如果您已创建了一个商业网站,您可能想要在站点上保留所购买的物品和服务的交易记录。这些信息能够可靠地保存在您的数据库中并通过用户的唯一 ID 来引用。它可用于确定购买交易是否完成,还可确定如果购买交易失败所应采取的操作步骤。这些信息还可用于通知用户使用您的站点所下的订单的状态。
-
数据挖掘 有关站点使用、访问者或产品交易的信息能够可靠地存储在数据库中。例如,业务发展部门可能希望使用从该站点收集的这些数据确定下一年的产品线或分销策略。市场营销部门可能希望查看有关您的站点的用户的人口统计信息。设计和支持部门可能希望查看交易并记下购买过程可以改进的区域。诸如 Microsoft SQL Server 之类的大多数企业级关系数据库提供了可适用于大多数数据挖掘项目的可扩展工具集。
在上述方案中通过将网站设计为在每一一般性阶段使用唯一 ID 重复查询该数据库,该站点对状态进行维护。在此方法中,用户感受到站点正记住和响应其本人。
使用数据库维护状态的优点为:
-
安全性 访问数据库需要严格的身份验证和授权。
-
存储容量 可以根据需要在数据库中存储尽可能多的信息。
-
数据持久性 可以根据需要在尽可能长的时间内存储数据库信息,这些信息不受 Web 服务器可用性的影响。
-
可靠性和数据完整性 数据库包括多种用于维护有效数据的功能,其中包括触发器和引用完整性、事务等。通过在数据库中(而不是在会话状态等对象中)保存有关事务的信息,可以更为方便地从错误恢复。
-
可访问性 存储在数据库中的数据可供众多的信息处理工具访问。
-
广泛的支持 有大量数据库工具可供使用,并且有许多自定义配置可供使用。
使用数据库维护状态的缺点为:
-
复杂性 使用数据库支持状态管理需要更复杂的硬件和软件配置。
-
性能注意事项 不佳的关系数据模型结构可能导致可伸缩性问题。此外,对数据库执行过多的查询可能会影响服务器性能。
服务器端方法状态管理摘要
下表列出了 ASP.NET 可用的服务器端状态管理选项,并提供了有关何时使用每种选项的建议。
状态管理选项 | 使用建议 |
---|---|
应用程序状态 | 可在以下情况下使用:存储由多个用户使用且更改不频繁的全局信息,而且不存在安全性问题。不要在应用程序状态中存储大量的信息。 |
会话状态 | 可在以下情况下使用:存储特定于单独会话的短期信息,并且需要较高的安全性。不要在会话状态中存储大量的信息。需要注意,将为应用程序中每一会话的生存期创建并维护会话状态对象。在支持许多用户的应用程序中,这可能会占用大量服务器资源并影响可缩放性。 |
配置文件属性 | 可在以下情况下使用:存储需要在用户会话过期后保留、并在对应用程序的后续访问中需要再次检索的特定于用户的信息。 |
数据库支持 | 可在以下情况下使用:存储大量信息,管理交易,或者信息必须可以经受得住应用程序和会话重新启动。数据挖掘十分重要,并且需要较高的安全性。 |