使用 ASP.NET 母版页可以为应用程序中的页创建一致的布局。单个母版页可以为应用程序中的所有页(或一组页)定义所需的外观和标准行为。然后可以创建包含要显示的内容的各个内容页。当用户请求内容页时,这些内容页与母版页合并以将母版页的布局与内容页的内容组合在一起输出。
母版页的工作原理
母版页实际由两部分组成,即母版页本身与一个或多个内容页。
母版页
母版页为具有扩展名 .master(如 MySite.master)的 ASP.NET 文件,它具有可以包括静态文本、HTML 元素和服务器控件的预定义布局。母版页由特殊的 @ Master 指令识别,该指令替换了用于普通 .aspx 页的 @ Page 指令。该指令类看起来类似下面这样。
如:<%@ Master Language="C#" %>
@ Master 指令可以包含的指令与 @ Control 指令可以包含的指令大多数是相同的。例如,下面的母版页指令包括一个代码隐藏文件的名称并将一个类名称分配给母版页。
可替换内容占位符
除会在所有页上显示的静态文本和控件外,母版页还包括一个或多个 ContentPlaceHolder 控件。这些占位符控件定义可替换内容出现的区域。接着在内容页中定义可替换内容。定义 ContentPlaceHolder 控件后,母版页可能看起来类似于下面这样。
内容页
通过创建各个内容页来定义母版页的占位符控件的内容,这些内容页为绑定到特定母版页的 ASP.NET 页(.aspx 文件以及可选的代码隐藏文件)。通过包含指向要使用的母版页的 MasterPageFile 属性,在内容页的 @ Page 指令中建立绑定。例如,一个内容页可能包含下面的 @ Page 指令,该指令将该内容页绑定到 Master1.master 页。
<%@ Page Language="C#" MasterPageFile="~/MasterPages/Master1.master" Title="Content Page"%>
母版页的优点
母版页提供了开发人员已通过传统方式创建的功能,这些传统方式包括重复复制现有代码、文本和控件元素;使用框架集;对通用元素使用包含文件;使用 ASP.NET 用户控件等。母版页具有下面的优点:
使用母版页可以集中处理页的通用功能,以便可以只在一个位置上进行更新。
使用母版页可以方便地创建一组控件和代码,并将结果应用于一组页。例如,可以在母版页上使用控件来创建一个应用于所有页的菜单。
通过允许控制占位符控件的呈现方式,母版页使您可以在细节上控制最终页的布局。
母版页提供一个对象模型,使用该对象模型可以从各个内容页自定义母版页。
母版页的运行时行为
在运行时,母版页是按照下面的步骤处理的:
用户通过键入内容页的 URL 来请求某页。
获取该页后,读取 @ Page 指令。如果该指令引用一个母版页,则也读取该母版页。如果这是第一次请求这两个页,则两个页都要进行编译。
包含更新的内容的母版页合并到内容页的控件树中。
各个 Content 控件的内容合并到母版页中相应的 ContentPlaceHolder 控件中。
浏览器中呈现得到的合并页
母版页和内容页路径
当请求某个内容页时,其内容与母版页合并,并且该页在内容页的上下文中运行。例如,如果获取 HttpRequest 对象的 CurrentExecutionFilePath 属性,则无论是在内容页代码还是母版页代码中,路径都表示内容页的位置。
母版页和内容页不必位于同一文件夹中。只要内容页的 @ Page 指令中的 MasterPageFile 属性解析为一个 .master 页,ASP.NET 就可以将内容页和母版页合并为一个单独的已呈现的页。
引用外部资源
内容页和母版页都可以包含引用外部资源的控件和元素。例如,两者都可以包含引用图像文件的图像控件,或包含引用其他页的定位点。
合并的内容和母版页的上下文是内容页的上下文。这会影响在定位点上指定资源(如图像文件和目标页)的 URL 的方式。
服务器控件
在母版页上的服务器控件中,ASP.NET 动态修改引用外部资源的属性的 URL。例如,可以将一个 Image 控件放置于一个母版页上并将其 ImageUrl 属性设置为相对于母版页。在运行时,ASP.NET 会修改 URL 以便其在内容页的上下文中正确解析。
ASP.NET 会在下面的情况下修改 URL:
URL 为某个 ASP.NET 服务器控件的属性。
该属性在该控件中内部标记为一个 URL。(该属性 (property) 用属性 (attribute) UrlPropertyAttribute 来标记。)在实际情况中,采用这种方式标记通常用于引用外部资源的 ASP.NET 服务器控件属性。
母版页与主题
不能直接将 ASP.NET 主题应用于母版页。如果向 @ Master 指令添加一个主题属性,则页在运行时会引发错误。
但是,主题在下面这些情况中会应用于母版页:
如果主题是在内容页中定义的。母版页在内容页的上下文中解析,因此内容页的主题也会应用于母版页。
如果通过在 pages 元素(ASP.NET 设置架构)元素中包含主题定义来将整个站点配置为使用主题。
限定母版页的范围
页级 可以在每个内容页中使用页指令来将内容页绑定到一个母版页,如下面的代码示例中所示。
<%@ Page Language="C#" MasterPageFile="MySite.Master %>
应用程序级 通过在应用程序的配置文件 (Web.config) 的 pages 元素中进行设置,可以指定应用程序中的所有 ASP.NET 页(.aspx 文件)都自动绑定到一个母版页。该元素可能看起来类似于下面这样。
<pages masterPageFile="MySite.Master" />
如果使用此策略,则应用程序中的所有具有 Content 控件的 ASP.NET 页都与指定的母版页合并。(如果某个 ASP.NET 页不包含 Content 控件,则不应用该母版页。)
文件夹级 此策略类似于应用程序级的绑定,不同的是只需在一个文件夹中的一个 Web.config 文件中进行设置。然后母版页绑定会应用于该文件夹中的 ASP.NET 页。
母版页与内容页的互操作
在内容页同通过对象Page.Master来访问母版页的元素。
在母版页同通过ContentPlaceHolder1.Page来访问内容页的元素。
动态地附加母版页this.MasterPageFile = "~/NewMaster.master";
ASP.NET 母版页和内容页中的事件
母版页和内容页都可以包含控件的事件处理程序。对于控件而言,事件是在本地处理的,即内容页中的控件在内容页中引发事件,母版页中的控件在母版页中引发事件。控件事件不会从内容页发送到母版页。同样,也不能在内容页中处理来自母版页控件的事件。
在某些情况下,内容页和母版页中会引发相同的事件。例如,两者都引发 Init 和 Load 事件。引发事件的一般规则是初始化事件从最里面的控件向最外面的控件引发,所有其他事件则从最外面的控件向最里面的控件引发。请记住,母版页会合并到内容页中并被视为内容页中的一个控件,这一点十分有用。
下面是母版页与内容页合并后事件的发生顺序:
母版页控件 Init 事件。
内容控件 Init 事件。
母版页 Init 事件。
内容页 Init 事件。
内容页 Load 事件。
母版页 Load 事件。
内容控件 Load 事件。
内容页 PreRender 事件。
母版页 PreRender 事件。
母版页控件 PreRender 事件。
内容控件 PreRender 事件。
母版页和内容页中的事件顺序对于页面开发人员并不重要。但是,如果您创建的事件处理程序取决于某些事件的可用性,那么您将发现,了解母版页和内容页中的事件顺序很有帮助。
嵌套的 ASP.NET 母版页
母版页可以嵌套,让一个母版页引用另外的页作为其母版页。利用嵌套的母版页可以创建组件化的母版页。例如,大型网站可能包含一个用于定义站点外观的总体母版页。然后,不同的网站内容合作伙伴又可以定义各自的子母版页,这些子母版页引用网站母版页,并相应定义合作伙伴的内容的外观。
与任何母版页一样,子母版页也包含文件扩展名 .master。子母版页通常会包含一些内容控件,这些控件将映射到父母版页上的内容占位符。就这方面而言,子母版页的布局方式与所有内容页类似。但是,子母版页还有自已的内容占位符,可用于显示其子页提供的内容。下