ASP.NET and JQuery MVC Menu Part 1

April 24, 2009 · 4 minute read · Tags: ASP.NET MVC | jquery

One of the key differences between ASP.NET Web forms and ASP.NET MVC is that WebForms contained many controls which you could use on your web pages and MVC doesn’t.

Not that this is a bad thing, the difficult thing about WebForms was the horrendous html they generated and the hoops you had to go through to gain fine control over them.

In this series of posts I will describe how to create a fully functional Menu using Html, JQuery and some C# Helper Methods.

Part 1 – Creating an MVC Menu

Creating a menu in MVC is actually pretty straightforward once you realise you’re going to have to do some of the dirty work yourself.

Start with a standard Unordered List.

  1. <ul id="main-menu">
  2.     <li>
  3.         <a href="/">Homea>
  4.     li>
  5.     <li>
  6.         <a href="/ContactUs">Contact Usa>
  7.         <ul>
  8.             <li>
  9.                 <a href="/FindUs">How to find usa>
  10.             li>
  11.         ul>
  12.     li>
  13. ul>

Note that we have another unordered list inside the main list to create a hierarchical menu.

Now I know what you’re thinking, that’s not MVC that’s just HTML. So let’s make life easier for ourselves and introduce a helper method to render these list items for us.

  1. public static string ListItem(this HtmlHelper helper, string linkText, string actionName, string controllerName)
  2. {
  3.     TagBuilder builder = getListItem(helper, linkText, actionName, controllerName);
  4.     return builder.ToString();        
  5. }

Nothing fancy here, but note that we’re passing in the action and controller names. The actual work is done in the getListItem method.

  1. static TagBuilder GetListItem(HtmlHelper helper, string linkText, string actionName, string controllerName)
  2. {
  3.     var linkHtml = HtmlHelper.GenerateLink(helper.ViewContext.RequestContext, helper.RouteCollection, linkText, null, actionName, controllerName, null, null);
  4.  
  5.     var builder = new TagBuilder("li");
  6.  
  7.     var isCurrent = IsCurrentAction(helper, actionName, controllerName);
  8.  
  9.     if (isCurrent)
  10.     {
  11.         builder.MergeAttribute("class", "current");
  12.     }
  13.  
  14.     builder.InnerHtml = linkHtml;
  15.     return builder;
  16. }

This is where the fun starts (honestly!).

  1. First off we generate a link for the specified action and controller. This will work with whatever routing you have set up and generate a link to the action.
  2. We create a new TagBuilder to render our list item
  3. We’ll look at the IsCurrentAction method next, it checks if the specified action/controller is the one currently being presented to the user
  4. If this is the current Action then set the list item’s class to “current”
  5. Put the link inside the li tag

IsCurrentAction is pretty straightforward too…

  1. static bool IsCurrentAction(HtmlHelper helper, string actionName, string controllerName)
  2.         {
  3.             string currentControllerName = (string) helper.ViewContext.RouteData.Values["controller"];
  4.             string currentActionName = (string) helper.ViewContext.RouteData.Values["action"];
  5.  
  6.             if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) &&
  7.                 currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase))
  8.             {
  9.                 return true;
  10.             }
  11.  
  12.             return false;
  13.         }

So how would you use your new helper methods?

  1. <ul id="main-menu" class="menu collapsible">
  2.     <%= Html.ListItem("Home", "Index", "Home") %>
  3.     <%= Html.ListItem("Contact Us", "Index", "ContactUs") %>
  4. ul>

This will render the list items and put a class=”current” attribute on the one for the page currently being viewed.

Now an obvious problem with this approach is that you can’t embed sub menus (ULs within LIs). The way around this is to mimic the MVC framework itself and introduce new BeginListItem and EndListItem methods (ASP.NET MVC has BeginForm and EndForm).

  1. public static string BeginListItem(this HtmlHelper helper, string linkText, string actionName,string controllerName)
  2. {
  3.     string result;
  4.  
  5.     TagBuilder builder = GetListItem(helper, linkText, actionName, controllerName);
  6.     result = builder.ToString(TagRenderMode.StartTag);
  7.     result += builder.InnerHtml;
  8.  
  9.     return result;
  10. }

This opens the li tag. The EndListItem method closes it.

  1. public static void EndListItem(this HtmlHelper helper)
  2.         {
  3.             HttpResponseBase httpResponse = helper.ViewContext.HttpContext.Response;
  4.             httpResponse.Write("
  5. ");
  6.         }

And we can use these methods as follows.

  1. <%= Html.BeginListItem("Contact Us", "Index", "ContactUs")%>
  2.     <ul>
  3.         <%= Html.ListItem("Find Us", "Index", "FindUs")%>                   
  4.     ul>
  5. <% Html.EndListItem(); %>

Next Time

Up next is how to spice this menu up and make it all “interactivy” using JQuery,

Join the Practical ASP.NET Newsletter

Ship better Blazor apps, faster. One practical tip every Tuesday.

I respect your email privacy. Unsubscribe with one click.