Render HTML for Menu in MVC 3 Using SiteMapProvider
There are several good jQuery menu plugins but I like the old skool ASP.NET SiteMapProvider because I can declare my app roles in there and get security trimming for free. Add and configure the default XmlSiteMapProvider or customize one to override the IsAccessibleToUser method. Your choice. Then add this MenuHelper static class to your project:
public static class MenuHelper
{public static MvcHtmlString Menu(this HtmlHelper helper)
{ var sb = new StringBuilder(); sb.Append("<ul id='nav'>"); // Render each top level nodevar topLevelNodes = SiteMap.RootNode.ChildNodes;
foreach (SiteMapNode node in topLevelNodes)
{ sb.AppendLine("<li>"); sb.AppendFormat("<a href='{0}'>{1}</a>", node.Url, helper.Encode(node.Title)); if (node.HasChildNodes) { sb.AppendLine("<ul>");foreach (SiteMapNode childNode in node.ChildNodes)
{ sb.AppendLine("<li>"); sb.AppendFormat("<a href='{0}'>{1}</a>", childNode.Url, helper.Encode(childNode.Title)); sb.AppendLine("</li>");}
sb.AppendLine("</ul>");}
sb.AppendLine("</li>");}
// Close unordered list tag sb.Append("</ul>");return new MvcHtmlString(sb.ToString());
}
}
If this is the first helper for the project then add the namespace where your MenuHelper class lives to your Views Web.config file:
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="YOUR.NAMESPACE.GOES.HERE" />
</namespaces>
</pages>
</system.web.webPages.razor>
Good to go. Now in your _Layout.cshtml (razor) page you can swap out the default menu behavior and call the helper class:
<div id="menucontainer">
@Html.Menu()
</div>
That's all there is to it. Well that and doing some CSS work for designing it. In my current project I'm using jQuery to show and hide submenu links as well but that's another blog post.

My name is James Still and I'm a seasoned software developer living and working in Oregon USA. I'm an avid cyclist, backpacker, reader, stargazer, and I pick at the guitar from time to time. 
