日期:2013-10-21  浏览次数:20725 次

Jayesh Patel、Bryan Acker 和 Robert McGovern

Infusion Development

适用范围:

Microsoft ASP.NET 2.0

摘要:尽管 ASP.NET 2.0 与 ASP.NET 1.1 完全向后兼容,但还是为 ASP.NET 带来了大量的内部变化,包括代码模型、编译、页面生命周期等的变化。本文将概括介绍这些变化。



本页内容
引言
代码模型
编译
完全运行时编译(代码目录)
页面生命周期
可扩展性
高级缓存技术
性能
结论

引言
对于专业的 ASP.NET 开发人员来说,与 ASP.NET 2.0 有关的重要问题是内部发生了哪些变化。尽管新功能很有趣而且学起来很有意思,但对于真正想掌握这一技术的开发人员来说,ASP.NET 核心结构发生的变化才是最吸引他们的地方。在本白皮书中,我们将介绍自版本 1.x 以来,ASP.NET 2.0 内部结构发生了什么样的变化。

本白皮书介绍的主题对那些关注性能的开发人员以及寻求如何优化应用程序的技术设计师非常有用。具体来说,我们将介绍有关代码模型、编译、页面生命周期、可扩展性、性能和缓存的主要问题。

本文中的许多示例要求您对 ASP.NET、Visual Basic .NET 和/或 C# 语法有相当程度的了解。本文还在适当的地方提供了参考文档,就某些特定的主题展开深入的讨论。

返回页首
代码模型
也许 ASP.NET 2.0 内部工作方式最明显的变化是 ASP.NET Web 页面的创建方式的变化。本节将介绍内含代码模型发生的变化以及这些变化对 ASP.NET 开发的影响。

ASP.NET 1.x 中的代码模型
在 ASP.NET 1.x 中,供开发人员开发 Web 窗体的主要选择有两个。首先,开发人员可以参照传统的 ASP 模型并直接在 ASPX 页面中编写代码。此过程称为“内嵌代码”,它非常适用于简单的命令。然而,对于更复杂的代码而言,编写内嵌代码将为读取混合了表示 (HTML) 和功能(代码)的 Web 页面带来困难。在 ASP.NET 中,为了帮助解决这个问题,已更改了默认的编码方法。您可以在单独的、只包含代码的文件(称为“内含代码”文件)中编写业务逻辑和事件处理代码。内含代码模型将只包含代码的文件与包含表示标记的 ASPX 文件链接起来。通过将代码与表示相分离,开发小组可以让设计人员处理演示文件,而让开发人员处理代码文件,从而提高开发小组的工作效率。



图1:ASP.NET 1.x 代码模型

内含代码模型面临的主要困难在于如何将内含代码文件与 ASPX 页面保持同步。尽管从编程意义上来讲 ASPX 页面是从内含代码文件继承而来的,但实际上这两个文件是通过更复杂的关系联系在一起的。

有关 ASP.NET 1.x 中的内含代码模型的详细信息,请参见 MSDN Library 文章 Web Forms Code Model(英文)。

继承的复杂性
ASP.NET 的设计模式就是让开发人员使用 Microsoft Visual Studio .NET 将控件拖放到 ASPX 页面中。Visual Studio 然后将在内含代码文件中自动生成适当的支持代码。如果控件已被添加到 ASPX 页面中,则必须在内含代码文件中添加新代码。换句话说,尽管 ASPX 页面继承自内含代码文件,但实际上 ASPX 页面推动了内含代码文件的设计。

编译的复杂性
第二个同步问题就是如何编译文件。所有的内含代码文件以及所有的支持类都被编译到一个程序集中,并存储在 Web 应用程序的 /bin 目录中。应用程序的编译工作是在部署工作之前进行的。而另一方面,ASPX 页面也是在第一次被请求时在运行时编译的。ASP.NET 运行库实际上将 ASPX 页面编译到该页面自己的临时程序集中。

此过程的问题在于,无需更新内含代码程序集即可更改 ASPX 页面。也就是说,开发人员可以在部署后更改某个属性或更改 ASPX 页面上某个控件的类型,而无需更新内含代码文件,也不用重新编译应用程序的程序集。出现这种情况时,由于内含代码文件与所关联的 ASPX 页面不匹配,应用程序可能会遇到意外的错误。

ASP.NET 2.0 中的代码模型
ASP.NET 2.0 继续提供内嵌代码和内含代码模型。从内嵌代码模型的角度来说,除了 Microsoft Visual Studio 2005 支持单文件开发的方式有所变化外,基本上没做什么改动。有关 Visual Studio 2005 中的变化及其如何处理内嵌代码的详细信息,请参阅这篇文章(英文)。

ASP.NET 2.0 通过改变内含代码文件的本质解决了内含代码模型的继承和编译问题。在 ASP.NET 2.0 中,内含代码文件不再是 System.Web.UI.Page 类的完整实现。相反,内含代码文件是一个新的构造函数,称为“局部类”。局部类包含所有用户定义的代码,但是不包含 Visual Studio .NET 在 ASP.NET 1.x 中自动生成的任何管线和连接代码。请求包含新的内含代码文件的 ASPX 页面时,ASP.NET 2.0 运行库实际上将把 ASPX 页面和局部类合并成一个类,而不是两个单独的类。



图 2:ASP.NET 2.0 中的内含代码模型

局部类使用新的关键字(在 Visual Basic 中为 Expands,在 C# 中为 Partial)指示在运行时将该类中的代码与另一个类中的代码相合并。类似地,ASPX 页面使用新的指令(称为 compilewith)指示该页面与内含代码文件之间的关联。

比较内含代码文件
如果您熟悉传统的 ASP.NET 1.x 内含代码文件,您应该知道 Visual Studio 将插入自动生成的控件声明和初始化代码。这种自动生成的代码是内含代码文件与 ASPX 文件之间双向同步的直接结果。带有标签的典型 ASPX 页面具有一个对应的内含代码文件,该文件由许多自动生成的文本行构成。

列表 1:ASP.NET 1.x 中的内含代码文件

namespace WebApplication1
{
public class WebForm1 :System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label Label1;
private void Page_Load(object sender,
System.EventArgs e) { }
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}

自动生成的代码不仅定义标签(以粗体显示的行),还声明新的事件(页面加载)并自动将该事件绑定到自动生成的方法包装程序 (Page_Load())。

比较而言,同一个 ASP.NET 页面在 ASP.NET 2.0 中生成的内含代码文件更简洁。

列表 2:ASP.NET 2.0.x 中的内含代码文件

namespace ASP {
public partial class Webform1_aspx
{
}
}

开发人员可以自动访问 Label1,并根据需要添加事件。例如,可以添加 Page_Load 事件以初始化标签。

列表 3:在新的内含代码文件中添加事件

namespace ASP {
public partial class Webform1_aspx
{
void Page_Load(object sender, EventArgs e)
{
Label1.Text = "Hello ASP.NET 2.0";
}
}
}

事件语法可通过 Visual Studio .N