One challenge I am going to have as I build-out my site is
keeping the organizational structure of it in shape (especially if I keep adding
samples each week). I’m going to want to have some type of menu system that
helps users on the site navigate their way around. What I want to make sure I
avoid is having to manually build and then update this menu structure within
HTML every-time I make a change. Instead, what I want to-do is to define the
site link structure with a clean data-model that I can then dynamically
data-bind my UI against. The good news is that ASP.NET 2.0 makes this easy
with the new Site
Navigation system.
Using the Site Navigation system I can define the logical
“site map” structure of what my site looks like – specifically how the site
structure is logically laid out (this can be different to how they are
physically organized on disk), and how the different pages are organized in
relation to each other. I can then access this structure at runtime using the
new “SiteMap” property on each ASP.NET page and user-control. What is powerful
about this API is that I can also use it to keep track of where the current
request is within the site structure – as well as dynamically lookup a
request’s relation to other urls within the site (for example: what is the
“parent, “sibling” and “child” nodes in the site-map relative to the current
request). Even fancier, I can integrate the Site Map system with the new
ASP.NET 2.0 Role Management security features – so that I can view the
structure through the “trimmed view” of what a visiting user has permission to
see (for example: pages that are secured only for users in an admin role
wouldn’t show up in the Site Navigation model when a guest is visiting the
site). The combination of all these features makes it very easy to quickly
build menu navigation and bread-crumb UI. You can also use this
module to help your site integrate better with search engines like Google.
To define our Site Navigation structure, I’m going to use the
built-in XML Site Map Provider that ships with ASP.NET 2.0. Alternatively, if
I wanted to store the site-map structure in a database I could have configured
my site to use the cool new SQL Site
Map Provider (the beauty of the ASP.NET 2.0 provider model is that all the
code and data-binding logic to work against the Site Navigation system stays
the same regardless of which provider implementation you have configured).
The XML-file based provider uses XML files that by default
have the name “Web.SiteMap” to define the site hierarchy. To create one of
these files, right click on the project and choose “Add New Item” and the “Site
Map” item:
Figure 9
This will create an XML file with a default schema for
defining a site-layout. Note that Visual Web Developer provides automatic
intellisense for this XML structure.
For my particular sample, I choose to define the site
structure like so:
Listing 4
<?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 url="Samples_Basic/BasicSamples.aspx" title="Basic Data Samples"
description="Basic Data Samples">
<siteMapNode url="Samples_Basic/Sample1.aspx" title="Samples 1" description="Samples 1" />
<siteMapNode url="Samples_Basic/Sample2.aspx" title="Samples 1" description="Samples 2" />
<siteMapNode url="Samples_Basic/Sample3.aspx" title="Samples 1" description="Samples 3" />
<siteMapNode url="Samples_Basic/Sample4.aspx" title="Samples 1" description="Samples 4" />
</siteMapNode>
<siteMapNode url="Samples_Advanced/AdvancedSamples.aspx" title="Advanced Data Samples"
description="Advanced Data Samples">
<siteMapNode url="Samples_Advanced/Sample1.aspx" title="Samples 1" description="Samples 1" />
<siteMapNode url="Samples_Advanced/Sample2.aspx" title="Samples 1" description="Samples 2" />
<siteMapNode url="Samples_Advanced/Sample3.aspx" title="Samples 1" description="Samples 3" />
<siteMapNode url="Samples_Advanced/Sample4.aspx" title="Samples 1" description="Samples 4" />
</siteMapNode>
<siteMapNode url="About.aspx" title="About" description="About" />
</siteMapNode>
</siteMap>
It has a top-level node called “Home” – and then three
sub-nodes – “Basic Samples”, “Advanced Samples” and “About”. The “Basic
Samples” and “Advanced Samples” then have several sub-nodes beneath them.
Note that ASP.NET will automatically cache the Site Maps’
XML file so that it doesn’t get read on each request – instead it will only be
parsed and processed on the first request to the application, and then on
subsequent requests the cached version will be used (note: this will
automatically get re-generated anytime the file changes).
I can then programmatically use the SiteMap.CurrentNode
property within an ASP.NET page at runtime to get back a SiteMapNode object
that represents where the current request is within the above Site Map
definition – as well as what its parent, children, and sibling node urls are
(and what their friendly names are as well).