如果你曾经到过陌生的目的地旅行过,那么你一定知道地图的重要性—它们能够帮助使你的旅行更舒适些。这个道理对于网站来说是同样的。一个网站应该呈现给访问者一种简单而灵活的导航结构以便它们能够容易地导航到该网站的不同部分。asp.net 2.0提供了一种称为SiteMap的特征—它帮助你实现这一功能。本文将解释什么是站点地图并且描述如何开发使用它们的网站导航结构。
一、 SiteMap
一个站点地图是一个xml文件(具有一个.sitemap扩展名)—它能够详细地描述你的网站的整个导航布局。你可以使用站点地图文件来满足你的一切要求。
一个示例将有助于解释站点地图文件。图1显示了一个示例网站的目录结构。
图1:网站结构
图中,首页(Default.aspx)和Contact Us页面(contact.aspx)位于网站的根文件夹下。还有两个分别称为PRoducts和Services的子文件夹。每一个子文件夹下都有两个Web表单:分别相应于Product1.aspx和Product2.aspx,以及Service1.aspx和Service2.aspx。
现在,只要遵循如下的步骤,你就可以使用一个站点地图来描述这个网站的结构:
1. 使用VS.NET 2005创建一个新网站。
2. 右击该网站并且选择“Add New Item...”。
3. 从“Add New Item...”对话框中选择Site Map(见图2)并且命名它为Web.sitemap。
图2:添加一个新的站点地图
Key in the following XML markup in the web.sitemap file:
<?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="My Web Site">
<siteMapNode url="~/products/default.aspx" title="Products">
<siteMapNode url="~/products/product1.aspx" title="First Product" />
<siteMapNode url="~/products/product2.aspx" title="Second Product" />
</siteMapNode>
<siteMapNode url="~/services/default.aspx" title="Services">
<siteMapNode url="~/services/service1.aspx"title="First Service" />
<siteMapNode url="~/services/service2.aspx" title="Second Service" />
</siteMapNode>
<siteMapNode url="contact.aspx" title="Contact Us" />
</siteMapNode>
</siteMap>
站点地图文件的根是siteMap。它包含一个结点siteMapNode,并且根据你的网站结构,它可以包含若干siteMapNode结点。
这个siteMapNode标签具有四个重要的属性(参见表格1)。
属性
描述
title
显示页面的标题。这个属性经常由导航控件用于显示URL的标题。
url
显示这个结点描述的页面的 URL。
description
指定关于这个页面的描述。你可以使用这个描述来显示提示内容。
roles
通过使用安全整修(后面将讨论),这个属性指定允许存取这个页面的角色。
表格1:<siteMapNode>标签的重要属性
这就构成了你的站点地图。现在你可以把使用它作为导航目的。
二、 使用SiteMap的方式
你可以以三种常见方式来使用在前一节所创建的站点地图文件:
· 使用SiteMapPath控件
· 使用SiteMap数据源控件
· 使用SiteMap类
这个SiteMapPath控件允许你生成breadcrumb。图3显示出什么是breadcrumb。
图3:Breadcrumb导航
SiteMapPath控件显示各种层级的导航。例如,你可以点击父或根级别以往回导航或转到顶层。当然,你也可以定制导航层次。
ASP.NET 2.0中还带有一组良好的导航控件,包括TreeView和菜单。借助于SiteMap数据源控件,你可以把站点地图文件与这些控件绑定到一起。
有些情况下,内置的导航控件可能无法满足你的要求。在这种情况中,你可以以编程方式存取这个站点地图文件并且读各种siteMapNode结点。然后,你可以生成一个定制的导航结构—使用siteMapNode的title和URL属性。
三、 使用SiteMapPath控件
在详细讨论细节前,让我们首先创建我们需要的目录结构和Web表单。首先,把两个文件夹Products和Services添加到网站。然后,添加一个新的Master页面MasterPage.master。接着添加显示在表格2中的Web表单,并且确保当你添加它们时都为其设置master页面。
Web表单名
文件夹
Default.aspx
Website root
Contact.aspx
Website root
Default.aspx
Products
Product1.aspx
Products
Product2.aspx
Products
Default.aspx
Services
Service1.aspx
Services
Service2.aspx
Services
表格2:Web表单列表
现在,打开你前面添加的Master页面。把一个Label控件和一个SiteMapPath控件拖动到它上面。然后,把该Label的Text属性设置为“Welcome!”。
下列的列表显示了MasterPage.master页面中的所有标记:
<%@ Master Language="C#" AutoEventWireup="true"
CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Font-Size="XX-Large" ForeColor="Blue" Text="Welcome!"></asp:Label><br />
<asp:SiteMapPath ID="SiteMapPath1" runat="server"
Font-Names="Verdana" Font-Size="0.8em"PathSeparator=" : ">
<PathSeparatorStyle Font-Bold="True" ForeColor="#5D7B9D" />
<CurrentNodeStyle ForeColor="#333333" />
<NodeStyle Font-Bold="True" ForeColor="#7C6F57" />
<RootNodeStyle Font-Bold="True" ForeColor="#5D7B9D" />
</asp:SiteMapPath>
<br />
<br />
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
</div>
</form>
</body>
</html>
现在,从根文件夹打开Default.aspx。Default.aspx应该看似图4的样子。
图4:Default.aspx的示例运行
为了设计这个页面,添加一个具有4行和1列的表格。拖动一个Label控件到最上边一行并且设置它的Text属性为“欢迎来到我们的网站!”。然后,拖动三个HyperLink控件到剩下的行上,并且设置它们的Text和NavigateUrl属性,显示于表格3中。
HyperLink ID
Text属性
NavigateUrl属性
HyperLink1
Products
~/products/default.aspx
HyperLink2
Services
~/Services/default.aspx
HyperLink3
Contact Us
~/contact.aspx
表格3:设置HyperLinks的属性
下面的列表显示了Default.aspx中的完整标记:
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master"
AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1"
ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<center>
<table>
<tr>
<td width="60%">
<asp:Label ID="Label1" runat="server" Font-Size="X-Large"
Text="Welcome to our Web site!"></asp:Label></td>
</tr>
<tr>
<td width="60%">
<asp:HyperLink ID="HyperLink1" runat="server"
Font-Size="X-Large" NavigateUrl="~/Products/Default.aspx">Products
</asp:HyperLink></td>
</tr>
<tr>
<td width="60%">
<asp:HyperLink ID="HyperLink2" runat="server" Font-Size="X-Large"
NavigateUrl="~/Services/Default.aspx">Services
</asp:HyperLink></td>
</tr>
<tr>
<td width="60%">
<asp:HyperLink ID="HyperLink3" runat="server"
Font-Size="X-Large" NavigateUrl="~/Contact.aspx">Contact Us
</asp:HyperLink></td>
</tr>
</table>
</center>
</asp:Content>
现在,从Products文件夹下打开Default.aspx并且按照图5所示来设计它。
图5:Products文件夹的默认页面
表格4列举了在Web表单中所使用的所有超级链接。
HyperLink ID
Text属性
NavigateUrl属性
HyperLink1
First Product
~/products/product1.aspx
HyperLink2
Second Product
~/products/product2.aspx
表格4:Products文件夹下Default页面中的超级链接信息
遵循同样道理,从Services文件夹下设计Default.aspx,结果如图6所示。
图6.Services文件夹的默认页面
表格5列举出了使用于Web表单中的超级链接信息。
HyperLink ID
Text属性
NavigateUrl属性
HyperLink1
First Service
~/Services/service1.aspx
HyperLink2
Second Service
~/Services/service2.aspx
表格5:Products文件夹下Default页面中的超级链接信息
最后,把一个标签添加到每一个其它Web表单并且按表格6所示设置它的Text属性。
Web表单名
Label的Text属性
~/Contact.aspx
Contact Us
~/Products/Product1.aspx
First Product Details
~/Products/Product2.aspx
Second Product Details
~/Services/Service1.aspx
First Service Details
~/Services/Service2.aspx
Second Service Details
表格6:从剩下的Web表单中设置Label的Text属性
现在,从根文件夹下运行Default.aspx并且导航到Product1.aspx页面。图7显示了Web表单的示例运行情况。
图7:Product1.aspx的示例运行
注意,web.sitemap文件的title和URL属性是怎样用于生成“breadcrumbs”的。另外,还要注意,父级是怎样随着当前页面标题一起显示的。试一试导航到各种页面并观察SiteMapPath控件。
四、 使用SiteMap数据源控件
站点地图的使用并不仅限于SiteMapPath控件。你还可以把站点地图依附到可导航控件(例如TreeView)上。在下列例子中,你将使用相同的站点地图文件来实现与一个TreeView控件的绑定。
把一个新的Web表单SiteMapDataSourceDemo.aspx添加到网站上。然后,把一个SiteMap数据源控件(SiteMapDataSource1)和一个TreeView控件(TreeView1)拖动到表单上。把这个TreeView控件的DataSourceID属性设置为SiteMapDataSource1。另外,还要把该TreeView控件的ShowLines属性设置为true。下面是SiteMapDataSourceDemo.aspx页面中的完整的标记:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="SiteMapDataSourceDemo.aspx.cs"
Inherits="SiteMapDataSourceDemo" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1"
ShowLines="True">
</asp:TreeView>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
</form>
</body>
</html>
现在,运行这个Web表单以观察相同的导航结构是怎样被自动生成到TreeView中的(见图8)。
图8:把网站地图文件绑定到一个TreeView控件
五、 使用SiteMap类
在SiteMapPath或TreeView控件中显示站点地图数据效果太好了。然而,有时你可能需要设计定制生成逻辑。例如,你可能想开发一个定制的导航控件—它仅为了垂直地显示其父级。在这样的情况下,你需要以编程方式来存取这个站点地图文件。SiteMap类允许你准确地实现这一点。
这个SiteMap路径具有两个重要的属性:RootNode和CurrentNode。它们的类型都是SiteMapNode,并且它们都能使你分别参考站点地图的根结点和当前结点。表格7列举了SiteMapNode类的一些重要的属性。
属性
描述
ChildNodes
代表当前结点的所有子结点的集合
HasChildNodes
指示是否站点地图结点具有子结点(true/false)
Title
返回在站点地图文件中指定的title属性的值
Url
返回在站点地图文件中指定的url属性的值
Description
返回在站点地图文件中指定的description属性的值
ParentNode
指出当前结点的父站点地图结点的参考
表格7:SiteMapNode类的一些重要的属性
下面的示例使用了SiteMap路径来存取一个站点地图文件的单个结点。然后,以编程方式把它们添加到一个TreeView控件。
添加一个称为SiteMapCustom.aspx的Web表单。然后,把一个TreeView控件拖动到其上。把列表代码添加到这个Web表单的Page_Load事件:
protected void Page_Load(object sender, EventArgs e)
{
int count = SiteMap.RootNode.ChildNodes.Count;
for (int i = 0; i < count; i++)
{
SiteMapNode smNode=SiteMap.RootNode.ChildNodes[i];
TreeNode tvNode = new TreeNode(smNode.Title, "", "", smNode.Url, "");
TreeView1.Nodes.Add(tvNode);
if (smNode.HasChildNodes)
{
int childCount=smNode.ChildNodes.Count;
for (int j = 0; j < childCount; j++)
{
SiteMapNode smChildNode = smNode.ChildNodes[j];
TreeNode tvChildNode = new TreeNode(smChildNode.Title,
"", "",
smChildNode.Url, "");
tvNode.ChildNodes.Add(tvChildNode);
}
}
}
}
在这里,你首先得到根结点中的子结点的总数。然后,你循环遍历根结点的ChildNodes集合。在每一次遍历中,你都会创建一个新的TreeNode类的实例并且在它的构造器中指定它的标题和url。然后,你把这个TreeNode添加到TreeView的Nodes集合中。然后,你检查是否当前SiteMapNode有任何子结点。如果有,你就对之进行遍历,重复TreeNode创建过程。注意,这一次你把新的TreeNodes添加到当前TreeNode对象的ChildNodes集合中。
注意,因为你知道只存在两级的嵌套,所以你在循环中使用了2。为了使得你的逻辑更具有一般性,你可以使用递归来填充TreeView。
运行Web表单,那么你将再次看到类似于图8所示的内容。
六、 使用安全整修
经常情况下,网站都要实现基于角色的安全模式。例如,你可以在你的应用程序中具有不同的角色,例如系统管理员,产品测试员和服务测试员。在这样的情况中,你经常需要控制显示给用户的站点导航链接。例如,如果当前登录的用户属于产品测试员角色,那么你可能仅想显示与产品相联系的链接,而隐藏任何其它链接。一种处理角色的方法是使用手工编码,但是,它要求以编程方式实现所有的授权逻辑。幸好,站点地图文件和SiteMap数据源控件一起提供了一种称为安全整修的特征来帮助你。
为了测试安全整修,你需要启动你的网站的会员和角色特征。打开web.config文件并且在其中加入下列标记:
<authentication mode="Forms" />
<authorization>
<deny users="?"></deny>
</authorization>
在此,你已经把认证模式设置为Forms。你还可以设置授权规则,这样以来匿名的用户都会被禁止存取此网站。然后,你需要启动角色管理特征—通过把下列标志添加到web.config文件中:
<roleManager enabled="true" />
然后,从VS.NET菜单下选择“WebSite>ASP.NET Configuration”以打开Web站点管理工具。使用这个工具来添加两个角色:ProductTesters和ServiceTesters(参考图9)。当一个属于ProductTesters角色的用户签入时,你只想实现把与产品相关的链接显示在导航TreeView控件中。同样,当一个属于ServiceTesters角色的用户签入时,应该只在TreeView中显示与服务相关的链接。
图9:使用Web站点管理工具添加角色
使用Web站点管理工具创建两个用户,分别叫user1和user2。把user1添加到ProductTesters角色,把user2添加到ServiceTesters角色(见图10)。
图10:使用Web站点管理工具创建用户
注意:默认地,用户和角色信息被存储在你的网站的App_Data文件夹下的ASPNETDB数据库中。这个数据库是由ASP.NET自动创建的,如果它不存在的话。
现在,把一个新的站点地图文件SecurityTrimming.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="My Web Site">
<siteMapNode title="Products" roles="ProductTesters">
<siteMapNode url="~/products/product1.aspx" title="First Product" />
<siteMapNode url="~/products/product2.aspx" title="Second Product" />
</siteMapNode>
<siteMapNode title="Services" roles="ServiceTesters">
<siteMapNode url="~/services/service1.aspx" title="First Service" />
<siteMapNode url="~/services/service2.aspx" title="Second Service" />
</siteMapNode>
<siteMapNode url="contact.aspx" title="Contact Us" />
</siteMapNode>
</siteMap>
这里的大多数标记与在web.sitemap文件中的相同。然而,这里有一个重要的属性添加到了Products和Services—siteMapNodes:roles。这个roles属性指定能够存取这个结点及其子结点的角色。因为与产品相联系的链接仅显示给属于ProductTesters角色的用户,你要把Products siteMapNode的roles属性设置为ProductTesters。遵循相同的道理,你要把Services siteMapNode的roles属性设置为ServiceTesters。不具有指定的roles属性的siteMapNodes对于所有用户都可存取。另外,还应注意,Products和Services结点不再具有指定的URL属性。
现在,你需要配置站点地图提供者并且启动安全整修以便SiteMap数据源控件能够按照你的要求行动。把下列标记添加到web.config文件中:
<siteMap defaultProvider="myprovider" enabled="true">
<providers>
<add name="myprovider"
type="System.Web.XmlSiteMapProvider "
siteMapFile="SecurityTrimming.sitemap"
securityTrimmingEnabled="true" />
</providers>
在此,你添加了<siteMap>节并且指定一个指向SecurityTrimming.sitemap文件的提供者。注意,这里的securityTrimmingEnabled属性被设置为true以支持安全整修。在你配置完<siteMap>节后,这个SiteMap数据源控件自动地从这个节中“拾取”这些设置。
把一个称为Login.aspx的新的web表单添加到网站上。然后,把一个Login控件拖动到它上面并且设置它的DestinationPageUrl属性为“~/SiteMapDataSourceDemo.aspx”。注意,你在之前已经开发了SiteMapDataSourceDemo.aspx。
运行Login.aspx(参考图11)并且输入针对user1的凭证。
图11:登录页面
在你成功地登录以后,你应该看见如图12所示的TreeView。因为user1属于ProductTesters角色,所以隐藏了与服务相联系的链接。
图12:使用安全整修
七、 总结
站点地图是一XML文件—它包含你的Web站点结构的所有细节。你可以使用站点地图文件来生成导航结构。三种使用站点地图文件的常用方法分别是:使用SiteMapPath控件,使用SiteMap数据源控件,或使用SiteMap类。你还可以使用一个特征—称为安全整修来支持到生成的导航链接的基于角色的安全性。这些控件和类共同帮助为你的Web地点创建一个专业的导航结构。