An easily navigable web site is half of the battle. I wouldn’t write about the revolutionary navigation designs and ideas here, let the web designers struggle with that. In this post, only cool and standard developer navigation will be considered. So let’s begin!
Our syllabus states the following on this objective: when to extend site map provider, treeview menu vs. site map path, programmatically manipulating site map nodes, overriding menu rendering by controls adapters, filtering site map nodes based on user roles. A nice collection.
The foundation of ASP.NET site navigation is the SiteMap. Now there are some classes with this name, so let’s lay out a terminology. The SiteMap is the XML document from where the data originates. It populates the SiteMapDataSource data source object, which looks for the web.sitemap file to get its data. It also populates the SiteMapPath control, which is a graphical representation of the sitemap, and is also known as breadcrumbs. I never understand why do they call it that way, but I have no English background.
So what’s the big deal with the epic battle between SiteMapPath and TreeView? The secret is that TreeView actually uses the SiteMapDataSource control to gain its data, so it reflects any changes made in the SiteMapDataSource. However, SiteMapPath queries the underlying web.sitemap file, without the intervention of a datasource object, so changes made in the SiteMapDataSource won’t affect it.
A little info about web.sitemap: it must be placed in the root directory, must have a root element, but you can define sub sitemaps inside elements. So the following XML is valid:
<siteMapNode title=”Root” description=”Root”>
Now filtering site map nodes based on user roles seems to be a hard task, but rest assured. You only need to include one attribute in your web.config file. It’s called securityTrimmingEnabled, and it’s trims out the irrelevant nodes from the site map for given roles. But it’s a bit resource-intensive, since it iterates through all nodes. The solution for this is to add the roles=”*” property to the nodes you want to show anyway. These nodes will be omitted from checking.
When to extend the default site map provider? The answer is easy. You’d do so when:
- You want to change the data location from web.sitemap.
- You want to allow duplicate URLs in a sitemap.
- You’d like to use a different schema than the default one.
- You need a dynamic sitemap that’s generated on the fly.
There are two base classes to extend. If you’d only like to change the underlying data source, you should extend StaticSiteMapProvider. If you plan greater modifications, fall back to SiteMapProvider.
To programmatically manipulate site map nodes, you should response to the SiteMapResolve event. Then you should create a temporary site map node, and return that instead of the current one. Refer to the MSDN article below to see how to do it. A little introduction:
protected void Page_Load(object sender, EventArgs e)
SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(SiteMap_SiteMaResolve);
protected SiteMapNode SiteMap_SiteMapResolve(object sender, SiteMapResolveEventArgs e)
SiteMapNode node =SiteMap.CurrentNode.Clone();
node.Url = “anotherpage.aspx”;
As for the last objective: you should derive a custom class form the ControlAdapter base class. Then implement the logic you’d like and last, configure a .browser file to use it. I had a post about this in the old 70-562 series. You can find it here.