Microsoft & .NETASPSet Your Web Site's Navigation Structure Easily with ASP.NET 2.0 Site Maps

Set Your Web Site’s Navigation Structure Easily with ASP.NET 2.0 Site Maps

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

If you’ve ever traveled to unfamiliar destinations, you know the importance of maps. They help you to travel easily, making your journey more pleasurable. The same holds true for Web sites. A Web site should present visitors with a simple yet flexible navigation structure so that they can travel to various parts of the site easily. ASP.NET 2.0 provides a feature called SiteMap that helps you implement this functionality. This article explains what site maps are and describes how to develop Web site navigation structures that use them.


The SiteMap


A site map is an XML file (with a .sitemap extension) that details the overall navigational layout of your Web site. You can consume the site map file as per your requirement.


An example will help explain site map files. Figure 1 shows the directory structure of a sample Web site.



Figure 1: Web Site Structure


The home page (Default.aspx) and Contact Us page (contact.aspx) reside in the root folder of the Web site. There are two sub folders called Products and Services. Each has two Web forms: Product1.aspx and Product2.aspx, and Service1.aspx and Service2.aspx, respectively.


Now, by taking the following steps, you’ll use a site map to represent this Web site’s structure:



  1. Create a new Web site using VS.NET 2005.
  2. Right-click on the Web site and choose “Add New Item…”.
  3. Select Site Map from the “Add New Item…” dialog (see Figure 2) and name it Web.sitemap.

    Figure 2: Adding a New Site Map


  4. Key in the following XML markup in the web.sitemap file:

    <?xml version=”1.0″ encoding=”utf-8″ ?>
    <siteMap >
    <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 the site map file is siteMap. It contains a node called siteMapNode, and depending on your Web site structure, it can contain several siteMapNodes.


The siteMapNode tag has four important attributes (see Table 1).


















Attribute Description
title Indicates the title of the page. This attribute often is used by navigation controls to display the 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 By using security trimming (discussed later), this attribute specifies the roles that are allowed to access this page.

Table 1: Important Attributes of the <siteMapNode> Tag


This makes your site map. You now can think of using it for navigation purposes.


Ways to Consume SiteMap


You can consume the site map file created in the previous section in three common ways:



  • Use the SiteMapPath control
  • Use the SiteMap data source control
  • Use the SiteMap class

The SiteMapPath control allows you to render what are often called breadcrumbs. Figure 3 shows what breadcrumbs are.



Figure 3: Breadcrumb Navigation


The SiteMapPath controls display various levels of navigation. For example, you can click on the parent or root levels to navigate back or at the top level. And, of course, you can customize the navigation levels.


ASP.NET 2.0 also comes with a nice set of navigation controls, including TreeView and menu. With the SiteMap data source control, you can bind the site map file with these controls.


At times, the built-in navigation controls may not meet your requirements. In such cases, you can access the site map file programmatically and read various siteMapNodes. You then can render a custom navigation structure using the title and URL attributes of siteMapNode.


Using the SiteMapPath Control


Before delving into mode details, create the required directory structure and Web forms first. Begin by adding two folders called Products and Services to the Web site. Then, add a new Master Page called MasterPage.master. Add the Web forms shown in Table 2, and be sure to set the master page for all of them as you add them.






























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 you added previously. Drag and drop a Label control and a SiteMapPath control onto it (find the SiteMapPath control 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 for MasterPage.master:

<%@ Master Language=”C#” AutoEventWireup=”true”
CodeFile=”MasterPage.master.cs” Inherits=”MasterPage” %>
<html >
<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


To design this page, add a table with four rows and one column. Drag and drop a Label control in the uppermost 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 in Table 3.



















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 for 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>

Now, open Default.aspx from the Products folder and design it as shown in Figure 5.



Figure 5: Default Page of Products Folder


Table 4 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


Along similar lines, design Default.aspx from the Services folder as shown in Figure 6.



Figure 6: Default Page of Services Folder


Table 5 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 each of 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 the Product1.aspx page. Figure 7 shows the sample run of the Web form.



Figure 7: Sample Run of Product1.aspx


Note how the title and URL attributes from the web.sitemap file are 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 the SiteMap Data Source Control


The use of site maps is not limited just to the SiteMapPath control. You also can attach the site map to navigational controls such as TreeView. In the following example, you 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) to the form. Set the DataSourceID property of the TreeView to SiteMapDataSource1. Also, set the ShowLines property of the TreeView control to true. The following is the complete markup of SiteMapDataSourceDemo.aspx:

<%@ Page Language=”C#” AutoEventWireup=”true”
CodeFile=”SiteMapDataSourceDemo.aspx.cs”
Inherits=”SiteMapDataSourceDemo” %>
<html >
<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 observe how the same navigation structure is rendered automatically in the TreeView (see Figure 8).



Figure 8: Binding Site Map File to a TreeView


Using SiteMap Class


Displaying site map data in the SiteMapPath or TreeView control works great. However, sometimes you may need to devise custom rendering logic. For example, you may want to develop a custom navigation control that displays only the parent levels vertically. 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 are of type SiteMapNode, and both give you the reference of the root node and current node of the site map, respectively. Table 7 lists some of the important properties of the 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 the title attribute as specified in the site map file
Url Returns the value of the url attribute as specified in the site map file
Description Returns the value of the description attribute as specified in the site map file
ParentNode Gives reference of the parent site map node of the current node

Table 7: Important Properties of the SiteMapNode Class


The following example uses the SiteMap path to access the individual nodes of a site map file. Then, it programmatically adds 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, you first get the total number of child nodes in the root node. Then, you loop through the ChildNodes collection of the root node. With each iteration, you create a new instance of the TreeNode class and specify its title and url in its constructor. You then add this TreeNode to the Nodes collection of the TreeView. Next, you check if the current SiteMapNode has any child nodes. If it does, you iterate through them, repeating the TreeNode-creation process. Note that this time you add the new TreeNodes to the ChildNodes collection of the current TreeNode object.


Note that because you knew that there were only two levels of nesting, you 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 similar to Figure 8.


Using Security Trimming


Web sites 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, if the currently logged-in user belongs to the ProductTesters role, you may want the links related to products to be displayed and any others to be hidden. One way to deal with roles this way is via manual coding, but it involves 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 to help you.


To test security trimming, you need to enable membership and roles features on your Web site. Open the web.config file and add the following markup in it:

<authentication mode=”Forms” />
<authorization>
<deny users=”?”></deny>
</authorization>

Here, you’ve set the authentication mode to Forms. You also set the authorization rule such that anonymous users are denied access to the Web site. Next, you need to enable the 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 the Web Site Administration Tool. Use the tool to add two roles: ProductTesters and ServiceTesters (see Figure 9). When a user belonging to the ProductTesters role signs in, you want only the product-related links to display in the navigation TreeView. Similarly, when a user belonging to the ServiceTesters role signs in, only the service-related links should display in the TreeView.

Figure 9: Using the Web Site Administration Tool to Add Roles


Use the Web Site Administration Tool to create two users called user1 and user2. Add user1 to ProductTesters role and user2 to ServiceTesters role (see Figure 10).

Figure 10: Creating Users Using Web Site Administration Tool


Note: By default, user and role information is stored in the ASPNETDB database from the App_Data folder of your Web site. This database is created automatically by ASP.NET if it doesn’t exist already.

Now, add a new site map file named SecurityTrimming.sitemap to the Web site and key in the following markup:

<?xml version=”1.0″ encoding=”utf-8″ ?>
<siteMap >
<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 this markup is the same as that in the web.sitemap file. However, there is one important attribute added to the Products and Services siteMapNodes: roles. The roles attribute specifies the role to which this node and its child nodes are accessible. Because product-related links are to be displayed only to the users belonging to ProductTesters, you set the roles attribute of the Products siteMapNode to ProductTesters. Along the same lines, you set the roles attribute of Services siteMapNode to ServiceTesters. The siteMapNodes that do not have the roles attribute specified are accessible to all users. Also, note that the Products and Services nodes no longer have the URL attribute specified.

Now, you need to configure the site map provider and enable security trimming so that the SiteMap data source control can do what you require from it. Add the following markup to the web.config file:

<siteMap defaultProvider="myprovider" enabled="true">
<providers>
<add name="myprovider"
     type="System.Web.XmlSiteMapProvider "
     siteMapFile="SecurityTrimming.sitemap"
     securityTrimmingEnabled="true" />
</providers>

Here, you added the <siteMap> section and specified a provider pointing to the SecurityTrimming.sitemap file. Note that the securityTrimmingEnabled attribute is set to true to enable security trimming. After you configure the <siteMap> section, the SiteMap data source control automatically picks up the setting from this section.

Add a new Web form called Login.aspx to the Web site. Drag and drop a Login control on it and set its DestinationPageUrl property to “~/SiteMapDataSourceDemo.aspx”. You developed SiteMapDataSourceDemo.aspx previously (refer to the section titled “Using the SiteMap Data Source Control”).

Run Login.aspx (see Figure 11) and enter the credentials for user1.

Figure 11: Login Page

After you log in successfully, you should see the TreeView as shown in Figure 12. Because user1 belongs to the ProductTesters role, the service-related links are hidden.

Figure 12: Security Trimming in Action

What Have You Learned?

Site map is an XML file that details the structure of your Web site. You can consume the site map file to generate navigation structures. The three common ways to consume site map files are by using the SiteMapPath control, the SiteMap data source control, or the SiteMap class. You also can use a feature called security trimming to enable role-based security to the navigation links rendered. These controls and classes together help you create a professional navigation structure for your Web sites.

Download the Code

Download the code that accompanies the examples in this article.

About the Author

Bipin Joshi is the founder and owner of BinaryIntellect Consulting, where he conducts professional training programs on .NET technologies. He is the author of Developer’s Guide to ASP.NET 2.0 and co-author of three WROX press books on .NET 1.x. He also is a Microsoft MVP, member of ASPInsiders, MCAD, and MCT.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories