If you have been using the ASP.NET MVC framework, you possibly have been searching for something like the classic ASP.NET sitemap. After you've played with it, you even found it useful! But not really flexible and easy to map to routes and controllers. To tackle that, last year, somewhere in August, I released a proof-of-concept sitemap provider for the ASP.NET MVC framework on my blog.
The blog post on sitemap provider I released back then has received numerous comments, suggestions, code snippets, … Together with Patrice Calve, we’ve released a new version of the sitemap provider on CodePlex: MvcSiteMap.
This time I’ll not dive into implementation details, but provide you with some of the features our sitemap provider erm… provides.
First things first: registering the provider
After downloading (and compiling) MvcSiteMap, you will have to add a reference to the assembly in your project. Also, you will have to register the provider in your Web.config file. Add the following code somewhere in the <system.web> section:
We’ve just told ASP.NET to use the MvcSiteMap sitemap provider, read sitemap nodes from the Web.sitemap file, use secrity trimming and cache the nodes for 10 minutes.
Defining sitemap nodes
Defining sitemap nodes is quite easy: add a Web.sitemap file to your project and popukate it with some nodes. Here’s an example:
<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMapNode title="Home" controller="Home" action="Index" isDynamic="true" dynamicParameters="*">
<mvcSiteMapNode title="About Us" controller="Home" action="About" />
<mvcSiteMapNode title="Products" controller="Products">
<mvcSiteMapNode title="Will be replaced in controller"
<mvcSiteMapNode title="Account" controller="Account">
<mvcSiteMapNode title="Login" controller="Account" action="LogOn" />
<mvcSiteMapNode title="Account Creation" controller="Account" action="Register" />
<mvcSiteMapNode title="Change Password" controller="Account" action="ChangePassword" />
<mvcSiteMapNode title="Logout" controller="Account" action="LogOff" />
Too much info? Let’s break it down. The sitemap consists of several nodes, defined by using a <mvcSiteMapNode> element. Each node can contain other nodes, as you can see in the above example. A node should also define some attributes: title and controller. Title is used by all sitemap controls of ASP.NET, controller is used to determine the controller to link to. Here’s a list of possible attributes:
||Title of the node.
||Controller the node should link to.
||Action method of the specified controller the node should link to.
||A key used to identify the node. Can be specified but is generated by the MvcSiteMap sitemap provider when left blank.
||Specifies if this is a dynamic node (explained later)
||When isDynamic is set to true.
||Specifies which parameters are dynamic. Multiple can be specified using a comma (,) as separator.
||When visibility is set to InSiteMapPathOnly, the node will not be rendered in the menu.
||Any other parameter will be considered to be an action method parameter.
Regarding the wildcard (*), here’s a sample sitemap node:
<mvcSiteMapNode title="Contact Maarten" controller="About" action="Contact" who=”Maarten” />
This node will map to the URL http://…./About/Contact/Maarten.
Using the sitemap
We can, for example, add breadcrumbs to our master page. Here’s how:
<asp:SiteMapPath ID="SiteMapPath" runat="server"></asp:SiteMapPath>
Looks exactly like ASP.NET Webforms, no?
In the table mentioned above, you may have seen the isDynamic and dynamicParameters attributes. This may sound a bit fuzzy, but it’s actually quite a powerful feature. Consider the following sitemap node:
<mvcSiteMapNode title="Product details" controller="Product" action="Details" isDynamic=”true” dynamicParameters=”id” />
This node will actually be used by the sitemap controls when any URL refering /Products/Details/… is called:
No need for separate sitemap nodes for each of the above URLs! One node is enough to provide your users with a consistent breadcrumb showing their location in your web application.
The MvcSiteMapNode attribute
Who said sitemaps should always be completely defined in XML? Why not use the MvcSiteMapNode attribute we created:
[MvcSiteMapNode(ParentKey="ProductsListCategory", Title="Product details", IsDynamic=true, DynamicParameters="id")]
public ActionResult Details(string id)
We are simply telling the MvcSiteMap sitemap provider to add a child node to the node with key “ProductsListCategory” which should have the title “Product details”. Controller and action are simply determined by the sitemap provider, based on the action method this attribute is declared on. Dynamic parameters also work here, by the way.
Do you have an example?
Yes! Simply navigate to the MvcSiteMap project page on CodePlex and grab the latest source code. The sitemap provider is included as well as an example website demonstrating all features.