作者:
-04-23 02:41 PM
任何动态Web应用程序都必须能够管理状态信息——的应用程序也不例外。在本文里,我会讨论处理两种类型状态信息的方法:请求状态和页面状态。我还会举出一些处理状态信息常用的最佳方法。
在本文里,我的内容会用到下面这两篇先前的发表文章里的概念:
《提供了新的状态管理技术》
《使用缓冲来优化你的Web应用程序》
使用请求状态
对 Web应用程序的请求由运行引擎在一个管线进程里处理。在这个请求被处理的时候,它就被从Web服务器(IIS)传递到HTTP应用程序,后者global.asax里的事件会对HTTP模块启动。在这些模块里,会话状态、安全以及其他信息会被处理。最后,专用的HTTP句柄会生成页面。图A说明了这一过程。
图A
请求处理的简化图
在处理过程中,信息被附加到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在结构上最大的一点不同之处是,它包括了一个允许基于事件开发的编程模型,而Visual Basic 6的是窗体模型。这个结构在页面保存任何服务器控件的ViewState,以此来创建基于静态窗体的开发环境的外观。
每个页面都包含有一个带有runat属性的FORM标签。在这个属性被碰到并被设置为文字字符串服务器(string literal server)的时候,一个FORM标签就被写到HTML流里,这个流会把窗体张贴回自身。此外,一个叫做__VIEWSTATE 的隐藏INPUT标签会被添加到这个窗体里;它含有一个经过base-64编码的字符串,用来表示窗体里控件属性的状态。
的自动ViewState管理的好处是,让你不再需要手动保存控件的状态,而且它以独立于浏览器的有效方式完成这一工作的。在页面被处理的时候,状态信息就被应用于页面控件,这就允许控件能够被程序自动填充而不需要担心重新填充它们。
停止自动ViewState管理
独立控件的ViewState和窗体作为一个整体或者作为Page指令的一个属性,能够通过设置代码里EnableViewState属性被控制。在缺省状态下,它被设置为True,但是把它设置为False就能够减少服务器接收和发送的数据量,从而提高性能。
当页面被加载或者张贴回服务器的时候就会出现一个问题:页面是从临时缓存(scratch)里被重建和重新执行的。换句话说,如果代码分离类包含有类层(class-level)的变量或者自定义属性,那么它们就不会被自动保存在ViewState里。但是,你可以编程来操控底层的System.Web.UI.StateBag对象,并使用Page和UserControl类的ViewState属性。
例如,想一想追踪用来给DataGrid排序的信息的情形。你可能要添加一些信息,页面需要这些信息来记住哪个数据列先前被排序以及是按什么顺序排的。Listing A是使用实现这一目的一种方法。
要注意,代码会首先检查以确定Page类的ViewState属性里是否存在SortField这个键。如果不存在,这些键就会被创建,并用要被排序的数据列和缺省的排序顺序(在这种情况下是升序)填充。新的排序数据列然后就会和StateBag里的信息相比较,如果相等话,排列的顺序就会被切换。最后,新的数据列和排列顺序会被放置回StateBag。
在保存Session状态这类信息的时候以这种方式使用StateBag有几个好处。尤其这只需要较小的系统开销,因为值不会被长期保存在任何地方,而是跟随窗体一起。此外,StateBag不会公开地传播信息,因为只有这个特别的Web窗体需要看见这些值。在经典的ASP里,开发人员不得不使用隐藏的窗体字段创建他们自己StateBag们的实现。
为处理Web应用程序的状态信息提供了一套完整强健的选择,在这一系列里我已经涉及了其中的很多。如果要总结一下何时以及如何使用这些选择,那么考虑一下图B里的表格。
图B
状态管理的选择
如果觉得《学会处理ASP.NET的页面和请求状态信息 (转载)》对你有帮助,请点赞、收藏,并留下你的观点哦!