ASP.NET 2.0 Site Navigation Features

Feb 2006 Update: Please also check out this new blog posting I did on Site Navigation.

 

The new Site Navigation features in ASP.NET 2.0 can make building navigation structures across a web-site much easier.

 

Scott Mitchell has published a good quick overview of the new ASP.NET 2.0 Site Navigation features if you aren’t familiar with them yet and want to come up to speed quickly.  There is also a ton of information on it on MSDN, and Danny Chen from the ASP.NET team has some extra great information on his blog. 

 

At a high-level, the new Site Navigation features allow you to define (outside of code or pages) the “site map” structure of how your site is laid out.  Specifically, it allows you to define the relationships between pages on the site – what is the “home” entry-point, what are the sub-sections of it, and how individual pages fit within it.  This information is cached by ASP.NET, and you can then get access to this sitemap structure at runtime. 

 

ASP.NET includes a basic built-in XML based SiteMap provider that allows you to define this site structure within an XML file whose default name is “web.sitemap” (note: you can change the name if you want).  For example, the below web.sitemap XML file example defines a sitemap with several levels of hierarchy (a homepage root, then three sub-nodes, and under the products node three additional sub-nodes):

 

<?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="The WebSite's Home Page">

     

      <siteMapNode url="Products.aspx" title="Products"  description="Product Listing Section of Site">

        <siteMapNode url="Software.aspx" title="Software"  description="Software Products" />

        <siteMapNode url="Hardware.aspx" title="Hardware"  description="Hardware Products" />

        <siteMapNode url="Services.aspx" title="Services"  description="Service Products" />

      </siteMapNode>

 

      <siteMapNode url="Documentation.aspx" title="Documentation"  description="Documentation about something"/>

      <siteMapNode url="About.aspx" title="About"  description="About the Company"/>

     

    </siteMapNode>

 

</siteMap>

 

The simplest way as a page developer to access the site-map at runtime (and figure out where the current page is within it) is by using the new “SiteMap” property on pages.

 

For example, the below code snippet shows a pretty simple scenario of how you could use the SiteMap system to dynamically build a “bread-crumb” UI on your page to provide a way for users visiting the site to see what page or section of the site they were within, and allow them to quickly navigate up the hierarchy chain:

 

        SiteMapNode node = SiteMap.CurrentNode;

 

        do

        {

            HyperLink link = new HyperLink();

            link.NavigateUrl = node.Url;

            link.Text = node.Title;

            SiteHierarchy.Controls.AddAt(0, link);

 

            Label label = new Label();

            label.Text = " >> ";

            SiteHierarchy.Controls.AddAt(0, label);

 

            node = node.ParentNode;

 

        }

        while (node != null);

 

By adding a placeholder or label control called “SiteHierarchy” in your .aspx page, then the above code will dynamically generate a hierarchy with this UI when the Software.aspx page is accessed:

 

>> Home >> Products >> Software

 

An even simpler way to achieve this is to use the new <asp:sitemappath> server control – which encapsulates and provides the breadcrumb UI logic for you (the control is also templated – so you can override the rendering using templates defined either inline or in an external skin file):

 

<asp:SiteMapPath ID="SiteMapPath1" runat="server">

 

You can also then use the new <asp:SiteMapDataSource> control to data-bind any control to the SiteMap (for example: you can databind a GridView, or DataList to one).  Two new controls in ASP.NET 2.0 are the <asp:treeview> and <asp:menu> that will probably be the most popular way to databind to the SiteMap and provide a hierarchical UI navigation structure. 

 

What is great about ASP.NET 2.0 is that you can do all these navigation things in conjunction with the new Master Pages feature – so that you could define a breadcrumb or menu in one .master file, and then have every page on the site pick it up and include it (and the navigation shown will be relative to the .aspx page using the master page – not the master page itself). 

 

The combination lets you whip up navigation structure and UI in only a few minutes, and provides the flexibility for you to dive down and customize things even further if necessary.

 

Answers to a couple of common questions about Site Navigation

 

I’ve seen a few common questions about the Site Navigation feature from folks at conferences and in blogs that I thought would be worth quickly answering:

 

>>> Question: With the default XML File Provider can you use a filename other than web.sitemap to store your site map information?

 

Answer: Yes.  The filename used with the XML File Provider can be specified in your web.config file (the default name we configure is web.sitemap).  This MSDN article shows how to-do this (among other things).

 

>>> Question: With the default XML File Provider can you partition your site map definition across multiple files (for example: have a site map file stored in a sub-directory of the site that defines the sitemap makeup of just that sub-directory)?

 

Answer: Yes – that is pretty easy to-do.  This MSDN article shows how to-do this.

 

>>> Question: Is it possible to filter what nodes are visible in the site-map based on the security role permissions of the current user visiting the site (for example: hide those nodes that they don’t have access to)?

 

Answer: Yes. This MSDN article show how to-do this.

 

>>> Question: Is it possible to dynamically add nodes into a site-map (for example: for forum or blog post listings underneath a leaf node) without having to write a custom SiteMapProvider?

 

Answer: Yes.  This MSDN Article and this blog post discuss how to-do this.

 

>>> Question: Can you localize site-maps (for example: have German and English content).

 

Answer: Yes.  This MSDN article shows how to-do this.

 

>>> Question: Can you define a site map definition in something other than an XML file (for example: instead use a database?).

 

Answer: Yes.  The Site Navigation system is provider based, which means that you can use any custom provider implementation to define the site-map hierarchy.  What is even cooler, is that you can optionally use multiple providers together – for example: use the XML provider for the overall structure, but maybe a blog specific provider that goes against a blog database to populate the nodes dynamically underneath a portion of the site.

 

Jeff Prosise also has a cool sample that he talks about here on how to build a SiteMapProvider that retrieves the sitemap structure from a database rather than the default XML file provider.  This MSDN article also links to a bunch of content on building your own SiteMap provider.

 

The next version of SharePoint (which is heavily integrated on top of ASP.NET 2.0) will also include a SharePoint specific Site Navigation provider that dynamically populates the site-map with the content contained within a SharePoint site.

 

Hope this helps,

 

Scott

31 Comments

  • Well, it's very useful.

  • Scott,

    Site Navigation system is a cool feature and i love it but it declaratively handles only the scenario where user roles either can access the page or not. Scenarios in app development like a page can be accessed by all the users but with varying capabilities (some roles has read only and others has update rights as well) with sitemap we may forced to do multiple copies of the page with almost same functionality (i am aware of an alternate implementation that we can give access to all user roles for a node and write logic in every page to check user roles and allow/deny features) . If the sitemap system has a way to indicate which role can have what rights on that node (read-only/ update) ,that would be a great feature.This can be extended to Server controls recognizing this right attribute and get enabled / disabled on the page for the corresponding user role.



    Thanks,

    Ajay

  • Scott,



    I really appreciate these posts! It's like you have a web cam looking over my shoulder, seeing exactly which areas of ASP.NET 2.0 I'm currently struggling with. There's a lot to learn and your blog makes it much easier.



    Jeff

  • Hi Ajay,



    What I'd typically recommend for those scenarios is to have the node show up in Site Navigation for everyone who has either read or write access, and then actually vary the capabilities within the page itself.



    One new control you can use to declaratively help with doing this is the &lt;asp:loginview&gt; control -- which allows you to declaratively specify role templates to vary content/capabilities. This provides an easy way to restrict/change the capabilities on the page itself.



    Hope this helps,



    Scott

  • Hi Scott, a not so typical question to this post, but I throw it here.



    &lt;i&gt;This information is cached by ASP.NET, and you can then get access to this sitemap structure at runtime.&lt;/i&gt;



    I would like to hear more info about this sentence, or caching mechanism. I read in one technical magazine -MENU article-, where the author adviced that developer has to MANUALY cache the menu, because every hit to menu hits the datasource, e.g. in this case web.sitemap.



    The article was a bit older(I think beta2), but do we still need to create a control wrapping menu control and cache it, or it is a a nonesense in athe article? I can provide a link if you wish, I won't be lazy promise :-)

  • Hi CowgaR,



    The XML based Site Naivgation system will cache the contents of the XML file in memory (and automatically regenerate the cache anytime the file changes). So you won't need to re-read the file on each request when you have a menu databound to the site navigation system.



    What the article is probably noting, though, is that it might still make sense to output cache the menu contents if it is a big menu -- since re-generating a tree of menu output with hundreds of items can still be pretty expensive. In that case it might make sense to encapsulate the menu control within a user control and perform output caching that way.



    Hope this helps,



    Scott

  • Hi Scott,

    Using the TreeView connected to a SiteMap, is it easy to implement PostBack functionality instead of using a URL? I'm using PostBack to prevent losing new entered data in a FormView.

  • Is there a quick way to get rid of that annoying arrow that separates the menus?

  • Hi mb,



    If by annoying arrow you mean the &quot;&gt;&gt;&quot; in my sample above &lt;g&gt;, then the answer is definitely yes. If you look at my code sample you'll see why this is showing up:



    Label label = new Label();

    label.Text = &quot; &gt;&gt; &quot;;

    SiteHierarchy.Controls.AddAt(0, label);



    You can change this to be whatever you want instead.



    Thanks,



    Scott

  • Scott,



    Do you know if you can change the default sitemapprovider through code?



    Also, can you set parameters of a provider through code?



    Here is an example:



    I want all navigation controls set to use the default provider; I don't want them set specifically to any one provider.



    Then, I want to be able to change the default provider through code rather than the web.config.



    I may even want to add a provider through code, and then set properties for that provider.



    Is this possible?



    Thanks,

    Roger

  • Thanx man .

    I want ask can i have 2 siteMap in one project?

  • Hi nasser,

    Yep -- you can have multiple sitemaps in a single project. You simple indicate in the parent sitemap where the child sitemaps are to implement the hierarchy.

    Hope this helps,

    Scott

  • Some thought.
    I can add role specification in the sitemapNode, but that seems tyo beuseless, cause I STILL need to config the access by web.config.

    I thought by specify a role in the sitemap it should render regaring to the usersroles, not hte settings in sitemap. otherwise, you get the sameeffect without anything in the sitemapNode.

    Do you understand my point?

  • Hi Pelle,

    All you should need to-do is to restrict role access in the authorization section for your urls, and then enable securitytrimming. You then don't need to set the roles in the web.sitemap file.

    Hope this helps,

    Scott

  • Hi Pelle,

    We've actually shipped the source code for the XML SiteMap provider here: http://msdn.microsoft.com/asp.net/downloads/providers/default.aspx

    This will allow you to dynamically load the sitemap however you want.

    Hope this helps,

    Scott

  • In my tests, i am not getting the full URL when I attach a sitemap via teh DataSource property.

    I do not get the "http://" portion and the postbacks do nothing.

    Seen this?

  • Hi Mike,

    Can you provide more details about the exact scenario you are doing?

    Thanks,

    Scott

  • hi,
    i would like to ask abou localization, if i want to store my localized texts in the DB, how can i config the sitemap to retrive it at runtime? if i don't want to use the resource files.

    Another question is can i at real-time add new set of child nodes when user clicks at the current leaf node, by mean of using another custom provider? Then i have to specifiy sitemapnode that points to this provider for every leaf node? That's an adhoc task to do.

    What i want exactly is to have static sitemap files and when it reaches the leaf node, it should retrive child nodes from DB at real-time (such as you have category as leaf node and then retrieve all products at run-time), how can i do that??

    Thanks

  • Scott,
    How can we add dynamic navigation to the sitemap/breadcrumb using the SiteMap Control?
    Maybe with an example I can explain...

    I have a site with the following structure:

    Category > MovieTitles > SoundTracksTitles > SoundTrackDetailInfo

    All of the information to generate the path above is stored in DB tables. How can we use the SiteMap control but still generate the breadcrumb path above?

    Thanks,
    Mukesh

  • Hi Mukesh,

    Danny Chen has a great blog on Site Navigation features, and has some articles on it about dynamically modifying the sitemap layout that should help: http://weblogs.asp.net/dannychen/

    Hope this helps,

    Scott

  • Hi Matt,

    This article describes how to use a database to store localization resources: http://www.codeproject.com/useritems/localization.asp

    Hope this helps,

    Scott

  • Hi Chris,

    Have you tested things using the approach I outlined here: http://weblogs.asp.net/scottgu/pages/Recipe_3A00_-Implementing-Role_2D00_Based-Security-with-ASP.NET-2.0-using-Windows-Authentication-and-SQL-Server.aspx

    This post shows how to use Windows Auth w/ Roles and control what nodes show up in a SiteMap.

    Thanks,

    Scott

  • Hi scott great article. 1 question though. rather than hide nodes based on roles is there a way of changing the style of the rendered node i.e the color?

    im presuming you can overide the render of the control, but am not sure how to implement this.

  • Hi,
    I have a question with respect to the security implementation of treeview using sitemap. Normally in the sitemap we can implement role based security but that is based on the Role based functionality provided by ASP.NET.
    Actually in our site we are using custom roles with our own role management and stuff. So is there a way to hide or show certain elements of the Sitemap in my menu based on the custom roles without using asp.net roles.
    Thanking you in advance.
    Khurram

  • the example is always showing the menu starting from level 1 with only one root, is there any way I can have more than one root in the first level? like the usual menu in windows explorer, ie File, Edit, View in the first level

  • Can we make this site navigation control like the one below:

    HOME | MAINMENU1 | MAINMENU2
    SUBMENU1-1 | SUBMENU1-2 | SUBMENU1-3

  • when i try to create a site map with more than one node at the top level, i encounter problems. it i possible only to have one root node?

  • Hi Freedom,

    What you can do is to leave the root node within your sitemap blank, and then have multiple nodes underneath it.

    Within the SiteMapDataSource control you can then set the ShowStartingNode property to false to omit the root node. When you do this you'll then have multiple top-level navigation links.

    Hope this helps,

    Scott

  • It does not work in case of response.redirect for a new page that is not in sitemapnode.
    Any solution?

  • I can dig it, but I have a question. You have to have your mouse positioned directlly over the "text" in the menu in order to navigate. I'm using CSS to pretty it up a bit and would like to be able to click anywhere in "table cell"...similar to click archive links on the left hand side of this page.

    Can this be done?

  • I've been doing some ASP.NET-work, and Opera is full of tabs now: "ScottGu's Blog : ...". Just confirms "Hope this helps", Scott, it does!

Comments have been disabled for this content.