Render HTML for Menu in MVC 3 Using SiteMapProvider

Tags: Knockout, pubsub, observer, MVC, jQuery, Ajax, EF, Validation, FluentValidation, Visual Studio 2010, ASP.NET, JSON, FullCalendar, Silverlight, Architecture, Vista, IIS, Generics, NHibernate, WCF, RIA Services, Visual Studio 2008, SQL, STORM!, Nullable, ChannelFactory, netTCPBinding, VSPAT, responsive, design, HTML5, CSS3, MVC WebAPI, MVC 4, WebAPI, JQuery Mobile, ScheduleWidget, recurring events, Ninject, Pluggable, CQRS DDD, Windows

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 node
            var 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.

1 Comment

  • Timur said

    Thank you for postion. Im trying to make menu with submenus and jquery effects, hope this will help )

Comments have been disabled for this content.