用户友好网站的一个共同特征是其具有一致的站点级页面布局和导航模式。 ASP.NET 2.0 引入了两种新功能,它们极大地简化了站点级页面布局和导航模式的实现过程。这两种功能是:母版页和网站导航。母版页允许开发人员创建具有指定的可编辑区域的站点级模板。随后,此模板可应用到网站中的 ASP.NET 页面上。这些 ASP.NET 页面只需为母版页中指定的可编辑区域提供相应内容 – 在使用母版页的所有 ASP.NET 页面中,母版页中的所有其它标记都相同。此模型允许开发人员定义并集中实现站点级页面布局。因此,开发人员可以方便地为所有页面创建一致的外观,并进行轻松的更新。
网站导航系统 为网页开发人员提供了定义站点地图的机制 , 同时还提供了API , 允许开发人员通过编程来查询该站点地图。使用新的导航 Web 控件( Menu 、 TreeView 和 SiteMapPath ),开发人员可以轻松地在普通的导航用户界面元素中呈现全部或部分站点地图。在本篇教程中,我们将使用默认的网站导航提供者,即,我们的站点地图将在 XML 格式的文件中定义。
为阐明这些概念并提高教程网站的可用性,在本篇教程中,我们将定义一个站点级页面布局,实现站点地图并添加导航 UI 。在本教程结束时,我们将拥有完善的网站设计方案来构建教程网页。
图1 :教程结束时完成的网站
第一个步骤是为该网站创建母版页。此时,我们的网站仅包含以下内容:Typed DataSet( Northwind.xsd ,位于 App_Code 文件夹中)、 BLL 类( App_Code 文件夹中的 ProductsBLL.cs 、 CategoriesBLL.cs 等)、数据库( NORTHWND.MDF ,位于 App_Data 文件夹中)、配置文件 (Web.config) 和一个 CSS 样式表文件 (Styles.css) 。我从前两篇教程中删除了使用 DAL 和 BLL 演示的页面和文件,因为我们还会在后面的教程中再次详细介绍这些示例。
图2 :此项目中的文件
要创建母版页,在Solution Explorer 中右键单击该项目的名称,选择 Add New Item 。然后,从模板列表中选择 Master Page 类型,将其命名为 Site.master 。
图3 :为网站添加一个新母版页
在此母版页中定义站点级页面布局。可以使用Design 视图添加所需的布局或 Web 控件,或者在Source 视图中手动添加标记。在我的母版页中,我利用级联样式表 进行定位,并使用了在外部文件 Style.css 中定义的带有 CSS 设置的样式。通过定义 CSS 规则,导航 <div> 的内容按以下方式完全定位:在左侧显示,固定宽度为 200 像素。
Site.master
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="Site" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head runat="server"> <title>Working with Data Tutorials</title> <link href="Styles.css" rel="stylesheet" type="text/css" /> </head> <body> <div id="wrapper"> <form id="form1" runat="server"> <div id="header"> <span class="title">Working with Data Tutorials</span> <span class="breadcrumb"> TODO: Breadcrumb will go here...</span> </div> <div id="content"> <asp:contentplaceholder id="MainContent" runat="server"> <!-- Page-specific content will go here... --> </asp:contentplaceholder> </div> <div id="navigation"> TODO: Menu will go here... </div> </form> </div> </body> </html>
母版页定义的内容包括固定的页面布局,以及使用该母版页的 ASP.NET 页面的可编辑的区域。你可以通过 ContentPlaceHolder 控件指出这些内容可编辑的区域,并在 <div> 内容中查看。我们的母版页只有一个 ContentPlaceHolder (MainContent) ,但在通常情况下,母版页可以有许多 ContentPlaceHolders 。
使用前面输入的标记,切换到显示母版页布局的 Design 视图。使用此母版页的所有 ASP.NET 页面都将显示如下的统一布局,而指定的MainContent区域则是每个页面不同的区域。
图4 :通过 Design 视图查看的母版页
定义完母版页后,我们将向网站添加 ASP.NET 页面。首先要添加的是 Default.aspx ,即网站的主页。在 Solution Explorer 中右键单击项目名称,选择 Add New Item 。从模板列表中选择 Web Form 选项,并为 Default.aspx 文件命名。同时,选中 "Select master page" 复选框。
图5 :添加一个新 Web 窗体并选中 “Select master page” 复选框
单击OK 按钮后,系统要求我们选择此 ASP.NET 新页面应使用的母版页。你的项目中可以有多个母版页,但我们的项目只有一个。
图6 :选择此 ASP.NET 页面应使用的母版页
选择母版页后,新的ASP.NET 页面将包含以下标记 :
Default.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server"> </asp:Content>
@Page 指令中引用了所用的母版页文件(MasterPageFile="~/Site.master") , 并且 ASP.NET 页面的标记中 定义了Content 控件对应母版页中定义的每个ContentPlaceHolder 控件,该控件的ContentPlaceHolderID 将Content 控件映射到特定的ContentPlaceHolder 。在 Content 控件中,你可以放置希望在相应的 ContentPlaceHolder 中显示的标记。将 @Page 指令的 Title 属性设置为 Home ,并向 Content 控件添加一些欢迎词。
Default.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Home" %> <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server"> <h1>Welcome to the Working with Data Tutorial Site</h1> <p>This site is being built as part of a set of tutorials that illustrate some of the new data access and databinding features in ASP.NET 2.0 and Visual Web Developer.</p> <p>Over time, it will include a host of samples that demonstrate:</p> <ul> <li>Building a DAL (data access layer),</li> <li>Using strongly typed TableAdapters and DataTables</li> <li>Master-Detail reports</li> <li>Filtering</li> <li>Paging,</li> <li>Two-way databinding,</li> <li>Editing,</li> <li>Deleting,</li> <li>Inserting,</li> <li>Hierarchical data browsing,</li> <li>Hierarchical drill-down,</li> <li>Optimistic concurrency,</li> <li>And more!</li> </ul> </asp:Content>
即使已经在母版页中定义了 <title> 元素,我们也可以在 ASP.NET 页面中使用 @Page 指令中的 Title 属性设置页面的标题。我们还可以使用 Page.Title 通过编程设置标题。注意,母版页对样式表(如 Style.css )的引用自动更新,因此,无论 ASP.NET 页面所在目录相对于母版页的位置如何,样式表都可以在所有 ASP.NET 页面中运行。
切换到Design 视图,我们可以看到页面在浏览器中是如何显示的。注意,在 ASP.NET 页面的 Design 视图中,只有内容可编辑区域可以编辑,除母版页中定义的 ContentPlaceHolder 标记外,其它标记都显示为灰色。
图7 :ASP.NET 页面的 Design 视图显示可编辑和不可编辑区域
当通过浏览器访问 Default.aspx 页面时,ASP.NET 引擎自动合并该页面的母版页内容和 ASP.NET 内容。最后在 HTML 中呈现合并后的内容,并将 HTML 内容发送到发出请求的浏览器。下一次访问主页时,如果母版页的内容已更新,所有使用该母版页的 ASP.NET 页面会重新将其内容与新的母版页内容合并。简而言之,母版页模型允许定义一个页面布局模板(母版页),该模板的变化会立即体现在整个网站中。
下面,我们会为网站添加其它 ASP.NET 页面数据,这些页面最终将用于演示各种报表的Demo。由于Demo的总数超过 35 个,因此我们只创建前几个(而不是所有)页面。此外,由于存在很多类别的Demo,为了更好地管理Demo,我们将为这些类别添加文件夹。现在,添加以下三个文件夹:
最后,根据图8 所示 Solution Explorer 中的内容添加新文件。在添加每个文件时,记住选中"Select master page" 复选框。
图8 : 添加以下文件
在管理由多个页面组成的网站时,其中一项挑战是为访问者提供一个便捷的方法在网站中导航。首先,必须定义网站的导航结构。然后,将此结构转换为可导航的用户界面元素,如菜单或 breadcrumb 。最后,我们需要维护整个过程,并在网站添加和删除页面时更新此过程。在出现 ASP.NET 2.0 之前,开发人员需要自己创建和维护网站的导航结构,并手动将导航结构转换为可导航的用户界面元素。然而,使用 ASP.NET 2.0 ,开发人员可以利用非常灵活的内置网站导航系统。
使用ASP.NET 2.0 网站导航系统,开发人员能够定义站点地图,并可以在随后通过可编程的 API 访问这些信息。 ASP.NET 包含了 一个站点地图提供者,希望以 XML 文件格式存储站点地图数据。但是,由于网站导航系统在 提供者模型 上构建,我们可以扩展该系统,允许其支持使站点地图信息序列化的其它方式。 Jeff Prosise 的文章 The SQL Site Map Provider You've Been Waiting For 显示了如何创建站点地图提供程序,将站点地图存储在 SQL Server 数据库中;另一个选择是创建基于文件系统结构的站点地图提供 者
然而,在本篇教程中,我们将使用ASP.NET 2.0 包含的默认站点地图提供程序。要创建站点地图,在 Solution Explorer 中右键单击项目的名称,选择 Add New Item ,然后选择 Site Map 选项。命名为 Web.sitemap ,单击 Add 按钮。
图9 :为项目添加站点地图
站点地图文件是 XML 文件。注意, Visual Studio 为站点地图结构提供 IntelliSense 。站点地图文件必须使用 <siteMap> 节点作为根节点,此根节点必须包含且仅包含一个 <siteMapNode> 子元素。而该 <siteMapNode> 子元素可以包含任意数量的 <siteMapNode> 派生元素。
定义站点地图来模拟文件系统结构。即,为上述三个文件夹中的每一个添加一个<siteMapNode> 元素,然后为这些文件夹中的所有 ASP.NET 页面添加 <siteMapNode> 子元素,如下所示 :
Web.sitemap
<?xml version="1.0" encoding="utf-8" ?> <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" > <siteMapNode url="~/Default.aspx" title="Home" description="Home"> <siteMapNode title="Basic Reporting" url="~/BasicReporting/Default.aspx" description="Basic Reporting Samples"> <siteMapNode url="~/BasicReporting/SimpleDisplay.aspx" title="Simple Display" description="Displays the complete contents of a database table." /> <siteMapNode url="~/BasicReporting/DeclarativeParams.aspx" title="Declarative Parameters" description="Displays a subset of the contents of a database table using parameters." /> <siteMapNode url="~/BasicReporting/ProgrammaticParams.aspx" title="Setting Parameter Values" description="Shows how to set parameter values programmatically." /> </siteMapNode> <siteMapNode title="Filtering Reports" url="~/Filtering/Default.aspx" description="Samples of Reports that Support Filtering"> <siteMapNode url="~/Filtering/FilterByDropDownList.aspx" title="Filter by Drop-Down List" description="Filter results using a drop-down list." /> <siteMapNode url="~/Filtering/MasterDetailsDetails.aspx" title="Master-Details-Details" description="Filter results two levels down." /> <siteMapNode url="~/Filtering/DetailsBySelecting.aspx" title="Details of Selected Row" description="Show detail results for a selected item in a GridView." /> </siteMapNode> <siteMapNode title="Customized Formatting" url="~/CustomFormatting/Default.aspx" description="Samples of Reports Whose Formats are Customized"> <siteMapNode url="~/CustomFormatting/CustomColors.aspx" title="Format Colors" description="Format the grid's colors based on the underlying data." /> <siteMapNode url="~/CustomFormatting/GridViewTemplateField.aspx" title="Custom Content in a GridView" description="Shows using the TemplateField to customize the contents of a field in a GridView." /> <siteMapNode url="~/CustomFormatting/DetailsViewTemplateField.aspx" title="Custom Content in a DetailsView" description="Shows using the TemplateField to customize the contents of a field in a DetailsView." /> <siteMapNode url="~/CustomFormatting/FormView.aspx" title="Custom Content in a FormView" description="Illustrates using a FormView for a highly customized view." /> <siteMapNode url="~/CustomFormatting/SummaryDataInFooter.aspx" title="Summary Data in Footer" description="Display summary data in the grids footer." /> </siteMapNode> </siteMapNode> </siteMap>
站点地图定义网站的导航结构,该结构为层次结构,用于描述网站的各个部分。 Web.sitemap 中的每个 <siteMapNode> 元素代表网站导航结构中的一个部分。
图10 :站点地图用于表示分层的导航结构
ASP.NET 通过 .NET Framework 的 SiteMap 类 显示站点地图的结构。该类的 CurrentNode 属性能够返回用户当前访问区域的相关信息;而 RootNode 属性能够返回站点地图的根节点( 在我们的站点地图中 , 根节点为Home )。CurrentNode 与 RootNode 属性都会返回 SiteMapNode 实例,这些实例含有的属性包括 ParentNode 、 ChildNodes 、 NextSibling 、 PreviousSibling 等,这些属性允许用户遍历站点地图层次结构。