+学会处理ASP.NET的页面和请求状态信息+

原文:http://www.zdnet.com.cn/developer
任何动态Web应用程序都必须能够管理状态信息——ASP.NET的应用程序也不例外。在本文里,我会讨论处理两种类型状态信息的方法:请求状态和页面状态。我还会举出一些处理状态信息常用的最佳方法。
在本文里,我的内容会用到下面这两篇先前的发表文章里的概念:
《ASP.NET提供了新的状态管理技术》
《使用ASP.NET缓冲来优化你的Web应用程序》


使用请求状态

对ASP.NET Web应用程序的请求由ASP.NET运行引擎在一个管线进程里处理。在这个请求被处理的时候,它就被从Web服务器(IIS)传递到HTTP应用程序,后者global.asax里的事件会对HTTP模块启动。在这些模块里,会话状态、安全以及其他信息会被处理。最后,专用的HTTP句柄会生成页面。A说明了这一过程。

图A

ASP.NET请求处理的简化图


在处理过程中,信息被附加到HttpContext对象里,这个对象能够通过Context属性最终在任何Page和UserControl类里被访问到。

除了允许访问当前请求的其他信息之外,HttpContext对象也能够被自定义的数据所填充,这些自定义数据能够被请求的其余内容访问。例如,global.asax代码分离(code-behind)类的BeginRequest事件能够包含读取数据的代码,这个数据库里放有动态页面布局的信息。这样这个信息就能够被放置在HttpContext对象里,并且能够从任何页面访问到,用以加载用户的控件和自动更改页面显示选项。

另一个例子是从Web页面取回用户的输入,然后把信息放到上下文里从而把信息传递给另一个页面,就像下面这样:

Me.Context.Items.Add("dept", txtDept.Text)
Me.Context.Items.Add("city", txtCity.Text)
Me.Server.Transfer("displayData.aspx")

在这种情况下,要注意缓冲区里的项目是能够被任何类型的数据所填充的名称-值对。但是对于要在另一个页面上取回的数据,Server对象的Transfer方法必须被用来执行下一个页面而不是带有查询字符串的Response.Redirect,因为后者会让浏览器创建一个对此页面的新请求,因此会创建一个新的HttpContext。而Server.Transfer在另一方面会在服务器端继续执行同一个请求,并保持已有的HttpContext。

使用页面信息

ASP.NET和ASP在结构上最大的一点不同之处是,它包括了一个允许基于事件开发的编程模型,而Visual Basic 6的是窗体模型。这个结构在页面保存任何ASP.NET服务器控件的ViewState,以此来创建基于静态窗体的开发环境的外观。
每个ASP.NET页面都包含有一个带有runat属性的FORM标签。在这个属性被碰到并被设置为文字字符串服务器(string literal server)的时候,一个FORM标签就被写到HTML流里,这个流会把窗体张贴回自身。此外,一个叫做__VIEWSTATE 的隐藏INPUT标签会被添加到这个窗体里;它含有一个经过base-64编码的字符串,用来表示窗体里控件属性的状态。

ASP.NET的自动ViewState管理的好处是,让你不再需要手动保存控件的状态,而且它以独立于浏览器的有效方式完成这一工作的。在页面被处理的时候,状态信息就被应用于页面控件,这就允许控件能够被程序自动填充而不需要担心重新填充它们。


停止自动ViewState管理
独立控件的ViewState和窗体作为一个整体或者作为Page指令的一个属性,能够通过设置代码里EnableViewState属性被控制。在缺省状态下,它被设置为True,但是把它设置为False就能够减少服务器接收和发送的数据量,从而提高性能。



当ASP.NET页面被加载或者张贴回服务器的时候就会出现一个问题:页面是从临时缓存(scratch)里被重建和重新执行的。换句话说,如果代码分离类包含有类层(class-level)的变量或者自定义属性,那么它们就不会被自动保存在ViewState里。但是,你可以编程来操控底层的System.Web.UI.StateBag对象,并使用Page和UserControl类的ViewState属性。

例如,想一想追踪用来给DataGrid排序的信息的情形。你可能要添加一些信息,页面需要这些信息来记住哪个数据列先前被排序以及是按什么顺序排的。Listing A是使用VB.NET实现这一目的一种方法。

要注意,代码会首先检查以确定Page类的ViewState属性里是否存在SortField这个键。如果不存在,这些键就会被创建,并用要被排序的数据列和缺省的排序顺序(在这种情况下是升序)填充。新的排序数据列然后就会和StateBag里的信息相比较,如果相等话,排列的顺序就会被切换。最后,新的数据列和排列顺序会被放置回StateBag

在保存Session状态这类信息的时候以这种方式使用StateBag有几个好处。尤其这只需要较小的系统开销,因为值不会被长期保存在任何地方,而是跟随窗体一起。此外,StateBag不会公开地传播信息,因为只有这个特别的Web窗体需要看见这些值。在经典的ASP里,开发人员不得不使用隐藏的窗体字段创建他们自己StateBag们的实现。

ASP.NET为处理Web应用程序的状态信息提供了一套完整强健的选择,在这一系列里我已经涉及了其中的很多。如果要总结一下何时以及如何使用这些选择,那么考虑一下B里的表格。
图B

图B

名称 何时使用 优势 劣势
Application对象 每个用户都需要看到相同的数据,而且数据是静态的 使用方便,和ASP的一样 无法超时,可能会碰到锁定的问题,保存在Web服务器的本地内存里
ASP.NET缓冲区 每个用户都需要看到相同的数据,而且数据是想对静态的 非常灵活,能够缓冲HTML和数据项目,能够超时和通知应用程序,性能良好 保存在Web服务器的本地内存里
Session对象 每个用户需要各自不同的私有数据 使用SQL Server或者状态服务就能够被保存在Web服务器之外 需要网站和页面额外的开销,影响性能
HttpContext 数据需要在单个请求里流动 对Web服务器影响很小,不需要查询字符串,能用于所有页面,能够有效地针对用户 只能使用当前请求访问数据
ViewState 数据需要被保持在单个页面的多次往返中 对Web服务器影响很小,不需要会话状态,能够保存复合对象(complex object) 大的对象会增加发送到浏览器的HTML的大小

ASP.NET状态管理的选择


posted @ 2006-09-04 18:20  ㊣鑫哥  阅读(280)  评论(0编辑  收藏  举报