1.2 ASP.NET网页代码模型

在上面已经基本了解了如何使用Visual Studio创建一个ASP.NET Web应用程序,也大致了解了ASP.NET网页的组成。本部分将继续上面的案例,详细讨论ASP.NET网页代码模型。

ASP. NET网页由两部分组成:

1)可视元素,包括标记、服务器控件和静态文本。

2)页的编程逻辑,包括事件处理程序和其他代码。

与此同时,ASP.NET提供两个用于管理可视元素和代码的模型,即单文件页模型和代码隐藏页模型。这两个模型功能相同,两种模型中可以使用相同的控件和代码。

1.2.1 单文件页模型

在单文件页模型中,页的标记及其编程代码位于同一个物理.aspx文件中。编程代码位于script块中,该块包含runat="server"属性,此属性将其标记为ASP.NET应执行的代码。以Login.aspx网页为例,如代码清单1-6所示。

代码清单1-6 Login.aspx


<%@Page Language="C#"%>

<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

protected void Page_Load(object sender, EventArgs e)

{

}

protected void bt_Login_Click(object sender, EventArgs e)

{

//将txt_UserName控件的内容存储到Session

if(this.txt_UserName.Text==String.Empty)

{

this.Session["UserName"]="World!";

}

else

{

this.Session["UserName"]=this.txt_UserName.Text.ToString();

}

//将页面转向到Default.aspx

Response.Redirect("Default.aspx");

}

</script>

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title></title>

</head>

<body>

<form id="form1"runat="server">

<div>

<asp:TextBox ID="txt_UserName"runat="server"Width="166px"></asp:TextBox>

<asp:Button ID="bt_Login"runat="server"onclick="bt_Login_Click"Text="登录"/>

</div>

</form>

</body>

</html>


在代码清单1-6中,将页的标记及其编程代码位于同一个物理.aspx文件Login.aspx中,这样运行的结果是不变的。

其中,script块可以包含页所需的任意多的代码。代码可以包含页中控件的事件处理程序(如代码清单1-6所示)、方法、属性及通常在类文件中使用的任何其他代码。在对该页进行编译时,编译器将生成和编译一个从Page基类派生或从使用@Page指令的Inherits属性定义的自定义基类派生的新类。例如,如果在应用程序的根目录中创建一个名为Login的新ASP.NET网页,则随后将从Page类派生一个名为ASP.Login_aspx的新类。对于应用程序子文件夹中的页,将使用子文件夹名称作为生成的类的一部分。生成的类中包含.aspx页中的控件的声明以及你的事件处理程序和其他自定义代码。

在生成页之后,生成的类将编译成程序集,并将该程序集加载到应用程序域,然后对该页类进行实例化并执行该页类以将输出呈现到浏览器。如果对影响生成的类的页进行更改(无论添加控件还是修改代码),则已编译的类代码将失效,并生成新的类。单文件ASP.NET网页中的页类的继承模型如图1-20所示。

figure_0054_0039

图 1-20 单文件网页的页类继承模型

1.2.2 代码隐藏页模型

对于代码隐藏模型相信大家不陌生,“Hello, World”Web应用程序项目采用的就是这种模型,它也是ASP.NET默认的页面代码模型。在代码隐藏模型中,页的标记和服务器端元素(包括控件声明)位于.aspx文件中,而你的页代码则位于单独的代码文件中。该代码文件包含一个分部类,类是使用partial关键字进行声明的,以表示该代码文件只包含构成该页的完整类的全体代码的一部分。而在页运行时,编译器将读取.aspx页以及它在@Page指令中引用的文件,将它们汇编成单个类,然后将它们作为一个单元编译为单个类。在分部类中,添加应用程序要求该页所具有的代码。此代码通常由事件处理程序构成,但是也可以包括你需要的任何方法或属性。

代码隐藏页的继承模型比单文件页的继承模型要稍微复杂一些。模型如下:

1)代码隐藏文件包含一个继承自基页类的分部类。基页类可以是Page类,也可以是从Page派生的其他类。

2). aspx文件在@Page指令中包含一个指向代码隐藏分部类的Inherits属性。

3)在对该页进行编译时,ASP.NET将基于.aspx文件生成一个分部类,此类是代码隐藏类文件的分部类。生成的分部类文件包含页控件的声明。使用此分部类,你可以将代码隐藏文件用做完整类的一部分,而无须显式声明控件。

最后,ASP.NET生成另外一个从在步骤3)中生成的类继承的类。生成的第二个类包含生成该页所需的代码。生成的第二个类和代码隐藏类将编译成程序集,运行该程序集可以将输出呈现到浏览器。

如图1-21所示,它显示了代码隐藏ASP.NET网页中的页类的继承模型。

figure_0055_0040

图 1-21 代码隐藏ASP.NET网页中的页类的继承模型(以Login.aspx为例)

注意 并非所有的.NET编程语言都可用于为ASP.NET网页创建代码隐藏文件,必须使用支持分部类的语言。例如,J#不支持分部类。因此也不支持为ASP.NET页创建代码隐藏文件。

1.2.3 选择属于自己的页模型

从功能上讲,单文件页模型和代码隐藏页模型功能完全相同。在运行时,这两个模型以相同的方式执行,而且它们之间没有性能差异。因此,页模型的选择取决于其他因素。例如,要在应用程序中组织代码的方式、将页面设计与代码编写分开是否重要等。

当然,在单文件模型和代码隐藏模型之间也存在着一些差别:

1)在代码隐藏模型中,不存在具有runat="server"属性的script块。(如果要在页中编写客户端脚本,则该页可以包含不具有runat="server"属性的script块。)

2)代码隐藏模型中的@Page指令包含引用外部文件(如Login.aspx.cs)和类的属性。这些属性将.aspx页链接至其代码。

当然,除了这些差异之外,它们也都有各自的优点。

1.单文件页模型的优点

通常,单文件模型适用于特定的页,在这些页中,代码主要由页中控件的事件处理程序组成。因此,它具有如下优点:

1)在没有太多代码的页中,可以方便地将代码和标记保留在同一个文件中,这一点比代码隐藏模型的其他优点都重要。例如,由于可以在一个地方看到代码和标记,因此研究单文件页更容易。

2)因为只有一个文件,所以使用单文件模型编写的页更容易部署或发送给其他程序员。

3)由于文件之间没有相关性,因此更容易对单文件页进行重命名。

4)因为页自包含于单个文件中,因而在源代码管理系统中管理文件稍微简单一些。

2.代码隐藏页的优点

代码隐藏页的主要优点在于它们更加适用于包含大量代码或多个开发人员共同创建Web应用程序项目。因此,它具有如下优点:

1)代码隐藏页可以清楚地分隔标记(用户界面)和代码。这一点很实用,可以在程序员编写代码的同时让设计人员处理标记。

2)代码并不会向仅使用页标记的页设计人员或其他人员公开。

3)代码重用度高,符合于面向对象的思想,可在多个页中重用代码。

在最后,建议你使用代码隐藏模型来进行ASP.NET Web应用程序项目的开发。