RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Nine ASP.NET Site Navigation Problem Solutions: Part 1 : Page 3

Find out how to use ASP.NET 2.0's site navigation controls to not only make building site navigation displays simple, but also solve real-world problems, such as hiding selected pages, or displaying "breadcrumbs."

#4: What's Under Your Bucket?
The previous solution showed how to display pails in between the HTML code for buckets. Displaying children of the active bucket after all buckets have been rendered is also a common requirement of site navigation, but requires a different approach. The second-level navigation in Figure 1 is a perfect example.

The approach is simple. Add a second SiteMapDataSource that exposes only the children of the active bucket:

   <asp:SiteMapDataSource ID="srcPails" runat="server" 
   ShowStartingNode="False" StartingNodeOffset="1" />
By setting StartingNodeOffset to 1, the example forces the starting point down one level from the bucket level, thus exposing the children of the currently active bucket. Setting the StartingNodeOffset to 2 works for third-tier pages under the active second-tier page, and so on.

#5: Lost in a Sea of Breadcrumbs
Displaying breadcrumbs in ASP.NET 2.0 is so ridiculously simple with the SiteMapPath control that this solution goes right to a more interesting problem—hiding certain breadcrumbs.

Hiding pages from the list of breadcrumbs is very useful in some circumstances, but its implementation is non-trivial. For example, suppose you want a set of pages to act as if they are children of the home page, yet look like third-level pages rather than buckets. Your sitemap might look like this:

  • Home (root version)
    • Home (bucket version)
      • Privacy Policy
      • Site Map
    • Articles
      • Article #1
      • Article #1
    • Solutions
      • ...
    • ...
The "Privacy Policy" page and the "Article #1" page must use different approaches to display their breadcrumbs. For example, Article #1 should display its breadcrumbs as Home > Articles > Article #1. It uses the root version of Home and displays its parent bucket. In contrast, the Privacy policy page should display its breadcrumbs as Home > Privacy Policy. But if it displays the root version of Home AND its bucket it will display home twice. So the problem is how to hide one of those pages from the breadcrumbs display.

You can solve the problem in three steps. First, by using the SiteMapPath templates in the page:

   <asp:SiteMapPath ID="smp" runat="server" PathSeparator="">
       <a href="/Default.aspx" >Home</a>
       <%# (IsSiteMapNodeVisible(Container.SiteMapNode) ? 
           Eval("Url," " // <a href=\"{0}\">") + 
           Eval("Title," "{0}</a>") : 
           "") %>
       <%# Eval("Title," " // {0}")%>
Second, by adding a visible="false" siteMapNode attribute to Web.sitemap as follows:

   <siteMapNode url="/" title="Home">
     <siteMapNode url="~/Default.aspx" title="Home" visible="false" />
And third, by adding an IsSiteMapNodeVisible() function that uses the visible property in the code-behind:

   protected bool IsSiteMapNodeVisible(SiteMapNode node) {
     // pages that don't contain an item in Web.sitemap return null
     if (node == null)
       return true;
     // most pages won't contain the visible attribute
     else if (node["visible"] == null)
       return true;
       // return true unless visible is set to "false"
       return !node["Visible"].Equals("false");
You should note two things about the preceding solution. First, Web.sitemap uses two different URL names to refer to Default.aspx. This is important because without it the .NET Framework will return the error:

   Multiple nodes with the same URL 'Default.aspx' were found. 
   XmlSiteMapProvider requires that sitemap nodes have unique URLs.
The .NET Framework requires URL's to be unique because behind the scenes it stores SiteMapNodes in a Dictionary object in memory. You could also get around this requirement by appending parameters to your URLs (e.g. Default.aspx?1, and Default.aspx?2).

Second, note that you cannot use PathSeparator if you ever plan to hide breadcrumbs. If you do set a path separator, either through the PathSeparator attribute or the PathSeparatorTemplate properties, the system displays the separator for your non-visible breadcrumbs—resulting in double separators.

The solution above approaches the problem by manually writing the "//" path separator in the NodeTemplate and CurrentNodeTemplate. You should note that doing this invalidates any NodeStyle-Font-Bold type attributes, because those will now apply to the separator as well as to the breadcrumb content. Consequently the NodeTemplate rolls its own formatting.

Even with the added twist of hiding certain breadcrumbs the ASP.NET 2.0 breadcrumb solution is remarkably simple compared to a custom solution. And what's truly impressive is how easy it is to extend the approach using SiteMapPath templates and custom attributes.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date