Using Site Maps to provide web site navigation
Introduction
If you anytime traveled to unknown areas you know the importance of maps.
They help you to travel easily making your journey pleasurable. The same holds
true for web sites. The visitors coming to your web sites should be presented
with simple yet flexible navigation structure so that they can travel to various
parts of your web site easily. ASP.NET provides a feature called SiteMap
that help you achieve this goal. In this article we will explore what site maps
are and how to develop web site navigation structures making use of them.
The SiteMap
A site map is an XML file that details the overall navigational layout of
your web site. You can then consume this site map file as per your requirement.
The site map file must have extension .sitemap.
Let's understand the site map files with an example. Have a look at Figure 1

Figure 1: Web site structure
Here, we have directory structure of a sample web site. The home page (Default.aspx)
and Contact Us page (contact.aspx) are residing in the root folder of the web
site. There are two sub folders called Products and Services. Each have two web
forms - Product1.aspx, Product2.aspx and Service1.aspx and Service2.aspx -
respectively.
Now let's represent this web site structure using a site map.
Create a new web site using Visual Studio. Right click on the web site and
choose "Add New Item...". Select Site Map from the "Add New Item..." dialog (see
Figure 2) and give name as Web.sitemap.

Figure 2: Adding a new site map
Now 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>
The root of site map file is siteMap. It further contains a node called
siteMapNode. Inside it contains several siteMapNodes depending on your web site
structure.
The siteMapNode tag has four important attributes. They are listed in Table
1:
Attribute |
Description |
title |
Indicates the title of the page. This attribute is often used by
navigation controls to display title for the URL. |
url |
Indicates the URL of the page that this node represents |
description |
Specifies description of this page. You can use this description to
show tooltips |
roles |
While using security trimming (discussed later) this attribute
specifies the roles that are allowed to access this page |
Table 1: Important attributes of <siteMapNode> tag
This makes your site map. You can now think of using it for navigation
purpose.
Ways to consume SiteMap
Site map files are often used to render some kind of navigation structure.
There are three common ways in which you can consume the site map file we just
created:
- Use SiteMapPath control
- Use SiteMap Data Source control
- Use SiteMap class
The SiteMapPath control allows you to render what is often called as
"breadcrumbs". Figure 3 shows what breadcrumbs are:

Figure 3: Breadcrumb navigation
The SiteMapPath controls displays various levels of navigation. You can click
on parent or root levels to navigate back or at the top level. You can of course
customize the navigation levels.
ASP.NET 2.0 comes with nice set of navigation controls that include TreeView
and menu. You can bind the site map file with these controls with the help of
SiteMap Data Source control.
At times the inbuilt navigation controls may not meet your requirement. In
such cases you can access the site map file programmatically and read various
siteMapNodes. You can then render a custom navigation structure using title and
url attributes of siteMapNode.
Using SiteMapPath control
Before we delve into mode details let's first create the required directory
structure and web forms. Begin by adding two folders to the web site called
Products and Services. Then add a new Master Page to the web site called
MasterPage.master. Add the web forms as shown in Table 2. Make sure to set
master page for all of them while adding.
Web Form name |
Folder |
Default.aspx |
Web site root |
Contact.aspx |
Web site root |
Default.aspx |
Products |
Product1.aspx |
Products |
Product2.aspx |
Products |
Default.aspx |
Services |
Service1.aspx |
Services |
Service2.aspx |
Services |
Table 2: List of web forms
Now, open the Master Page that we added previously. Drag and drop a Label
control and a SiteMapPath control on it (SiteMapPath control can be found in the
Navigation node of the VS.NET Toolbox). Set the Text property of the Label to
"Welcome!".
The following listing shows the complete markup of 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>
Now open Default.aspx from the root folder. The Default.aspx should look like
Figure 4.

Figure 4: Sample run of Default.aspx
In order to design this page, add a table with four rows and one column. Dran
and drop a Label control in the topmost row and set its Text property to
"Welcome to our web site!". Then drag and drop three HyperLink controls in the
remaining rows and set their Text and NavigateUrl properties as shown below:
HyperLink ID |
Text property |
NavigateUrl property |
HyperLink1 |
Products |
~/products/default.aspx |
HyperLink2 |
Services |
~/Services/default.aspx |
HyperLink3 |
Contact Us |
~/contact.aspx |
Table 3: Setting properties of HyperLinks
The following listing shows the complete markup of Defaule.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>
Now open Default.aspx from Products folder and design it as shown in Figure
5.

Figure 5: Default page of Products folder
The following table lists the HyperLinks used in the web form.
HyperLink ID |
Text property |
NavigateUrl property |
HyperLink1 |
First Product |
~/products/product1.aspx |
HyperLink2 |
Second Product |
~/products/product2.aspx |
Table 4: HyperLinks of default page from Products folder
On the similar lines design Default.aspx from Services folder as shown in
Figure 6:

Figure 6: Default page of Services folder
The following table lists the HyperLinks used in the web form.
HyperLink ID |
Text property |
NavigateUrl property |
HyperLink1 |
First Service |
~/Services/service1.aspx |
HyperLink2 |
Second Service |
~/Services/service2.aspx |
Table 5: HyperLinks of default page from Products folder
Finally, add one label to all the remaining web forms and set its Text
property as shown in Table 6:
Web Form name |
Text property of Label |
~/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 |
Table 6: Setting Text property of Labels from remaining web forms
Now, run the Default.aspx from the root folder and navigate to Product1.aspx
page. Figure 7 shows the sample run of the web form.

Figure 7: Sample run of Product1.aspx
Note how title and url attributes from the web.sitemap file is used to render
the "breadcrumbs". Also, note how the parent levels are displayed along with the
current page title. Try navigating to various pages and observe the SiteMapPath
control.
Using SiteMap Data Source control
The use of site maps is not limited just to SiteMapPath control. You can also
attach the site map to navigational controls such as TreeView. In this example
we will use the same site map file to bind with a TreeView.
Add a new web form called SiteMapDataSourceDemo.aspx to the web site. Drag
and drop a SiteMap Data Source control (SiteMapDataSource1) and a TreeView
(TreeView1). Set the DataSourceID property of the TreeView to
SiteMapDataSource1. Also, set ShowLines property of TreeView control to true.
Below is the complete markup of 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>
Now run the web form and see how the same navigation structure is
automatically rendered in the TreeView (Figure 8).

Figure 8: Binding site map file to a TreeView
Using SiteMap class
Displaying site map data in SiteMapPath or TreeView control works great.
However, at times you may need to device a custom rendering logic. For example,
you may want to develop a custom navigation control that displays only the
parent levels; that too in vertical direction. In such cases you need to access
the site map file programmatically. The SiteMap class allows you to do exactly
that.
The SiteMap path has two important properties - RootNode and CurrentNode.
Both of these properties are of type SiteMapNode and give you the reference of
root node and current node of the site map respectively. The Table 7 lists some
of the important properties of SiteMapNode class.
Property |
Description |
ChildNodes |
Represents the collection of all the child nodes of the current node |
HasChildNodes |
Indicates whether the site map node has child nodes (true/false) |
Title |
Returns the value of title attribute as specified in the site map
file |
Url |
Returns the value of url attribute as specified in the site map file |
Description |
Returns the value of description attribute as specified in the site
map file |
ParentNode |
Gives reference of the parent site map node of current node |
In the following example we will use SiteMap path to access the individual
nodes of site map file. We then programmatically add them to a TreeView control.
Add a new web form called SiteMapCustom.aspx. Drag and drop a TreeView
control on it. Add the following code to the Page_Load event of the web form.
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);
}
}
}
}
Here, we first get the total number of child nodes of the root node. Then we
loop through the ChildNodes collection of the root node. With each iteration we
create a new instance of TreeNode class and specify its title and url in its
constructor. We then add this TreeNode to the Nodes collection of the TreeView.
We check if the current SiteMapNode has any child nodes. If it does have child
nodes we iterate through them repeating the TreeNode creation process. Note that
this time we add the new TreeNodes to the ChildNodes collection of the current
TeeNode object.
Note that since we know that there are only two levels of nesting we used two
for loops. To make your logic more generic you may use recursion to populate the
TreeView.
Run the web form and you should again see something as shown in Figure 8.
Using security trimming
Web site often implement role based security schemes. For example, you may
have different roles in your application such as Administrators, ProductTesters
and ServiceTesters. In such cases you frequently need to control the site
navigation links shown to the users. For example you may want that if the
currently logged in user belongs to ProductTesters role then on the links
related to products should be displayed otherwise they should be hidden from
him. One way to deal this way is via manual coding but it will involve
programmatically taking care of all the authorization logic. Fortunately, the
site map file and SiteMap Data Source control together provide a feature called
security trimming that helps you achieve just that.
In order to test security trimming you need to enable membership and roles
features to your web site. Open the web.config file and add the following markup
in it:
<authentication mode="Forms" />
<authorization>
<deny users="?"></deny>
</authorization>
Here we set authentication mode to Forms. We also set authorization rule such
that anonymous users are denied access to the web site. We also need to enable
role management feature by adding the following tag to the web.config file:
<roleManager enabled="true" />
Next, select WebSite > ASP.NET Configuration from the VS.NET menu bar to open
Web Site Administration Tool. Using the tool add two roles - ProductTesters and
ServiceTesters (Figure 9). We want that when user belonging to ProductTesters
role signs in only the product related links should be displayed in the
navigation TreeView. Similarly when user belonging to ServiceTesters role signs
in only the service related links should be displayed in the TreeView

Figure 9: Adding roles using Web Site Administration Tool
Create two users using the Web Site Administration Tool called user1 and
user2. Add user1 to ProductTesters role and user2 to ServiceTesters role (Figure
10).

Figure 10: Creating users using Web Site Administration Tool
NOTE: By default user and role information is stored in ASPNETDB database
from App_Data folder of your web site. This database is automatically created by
ASP.NET if it doesn't exists.
Now add a new site map file named SecurityTrimming.sitemap to the web site
and key in the following markup in it:
<?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>
Most of the markup is the same as we wrote in web.sitemap file earlier.
However, there is one important attribute - roles - added to Products and
Services siteMapNodes. The roles attribute specifies the role for which this
node and its child nodes are accessible. Since Products related links are to be
displayed only to the users belonging to ProductTesters we set roles attribute
of Products siteMapNode to ProductTesters. On the same lines we set roles
attribute of Services siteMapNode to Servicetesters. The siteMapNodes that do
not have roles attribute specified are accessible to all the users. Also, note
that Products and Services nodes no longer have url attribute specified.
Now we need to configure the site map provider and enable security trimming
so that SiteMap Data Source control can do the needful for us. Add the following
markup in web.config file:
<siteMap defaultProvider="myprovider"
enabled="true">
<providers>
<add name="myprovider"
type="System.Web.XmlSiteMapProvider "
siteMapFile="SecurityTrimming.sitemap"
securityTrimmingEnabled="true" />
</providers>
Here, we add <siteMap> section and specify a provider pointing to
SecurityTrimming.sitemap file. Note that securityTrimmingEnabled attribute is
set to true to enable security trimming. Once we configure the <siteMap> section
the SiteMap Data Source control will automatically pickup setting from this
section.
Add a new web form to the web site called Login.aspx. Drag and drop a Login
control on it and set its DestinationPageUrl property to "~/SiteMapDataSourceDemo.aspx".
We developed SiteMapDataSourceDemo.aspx previously (refer section titled "Using SiteMap Data Source control").
Run the Login.aspx (Figure 11) and enter credentials for user1.

Figure 11: Login page
Once you login successfully you should see the TreeView as shown in Figure
12. Since user1 belongs to ProductTesters role the service related links are
hidden.

Figure 12 : Security Trimming in action
Summary
Site map is an XML file that details the structure of your web site. You can
consume site map file to generate navigation structures. There are three common
ways to consume site map files viz., using SiteMapPath control, using SiteMap
Data Source control and using SiteMap class. You can also enable role based
security to the navigation links rendered using a feature called security
trimming. These controls and classes together help you create a professional
navigation structure for your web sites.