When working with HTML and CSS there are some visual queues that you can add to enhance the user experience. One of these tricks is to highlight the menu button in your navigation. Most web applications do it, but how do you accomplish this in your current ASP.NET MVC application? First let’s look at what we are trying to do. Below you will see the header to the Aqua Bird Consulting site. You’ll notice that one of the buttons is different than the others; the button that relates to the page we are on is different.

Header to Aqua Bird Consulting site. Notice the "Home" button is highlighted.

Header to Aqua Bird Consulting site. Notice the "Home" button is highlighted.

If we look at the source of the page we’ll see that the home button has an id of “active”. Obviously you could accomplish the same thing by putting a class on the HTML element, but that’s another discussion. So how do you get the correct button to be active as we move around the site? There are two ways, I’ll first talk about the BAD way to do it.

 <ul>
    <li id="active">
        <a href="/"><span>Home</span></a>
    </li>
    <li>
        <a href="/About"><span>Company</span></a>
    </li>
    <li>
        <a href="/Services"><span>Services</span></a>
    </li>
    <li>
        <a href="/Portfolio"><span>Portfolio</span></a>
    </li>
    <li>
        <a href="/Products"><span>Products</span></a>
    </li>
    <li>
        <a href="/Contact"><span>Contact</span></a>
    </li>
  </ul>

The Bad

You could always place a value into ViewData, TempData, or even on your view model. This is bad because, now we are pulling visual elements down into our controller. This is a big no-no, and we would be violating the will of the MVC gods. Having the “Home” button highlighted doesn’t change the state of our underlying application (by underlying, I mean business logic). So don’t do this; it will definitely work but you’ll be in a world of pain if you decide to redesign your site or refactor.

The Good

The great thing about ASP.NET MVC and .NET 3.5 is the extensibility of it all. Everything is right there for you to access. So knowing that little fact about the extensibility of the ASP.NET MVC framework, you have to figure there is a way to know what Controller, Action, or even View we are on. For the scenario pertaining to the Aqua Bird Consulting site, we needed to link buttons to Controllers and Actions. Know let’s look at how we get the Controller and Action.

// helper is and HtmlHelper
var currentController =  helper.ViewContext.RouteData.Values["controller"].ToString();
var currentAction = helper.ViewContext.RouteData.Values["action"].ToString();

Cool! Nothing to it. Now all we need to do is check it on the view. I created an extension method, where you pass in a controller name, or a controller name and action pair. In addition to those parameters you pass in your designated output. I also have one where you can pass the controller name only, possibly for multipurpose controllers or sections.

public static string IsActive(this HtmlHelper helper, string controllerName, string output)
{
   var currentController = helper.ViewContext.RouteData.Values["controller"].ToString();
   return (currentController == controllerName) ? output : string.Empty;
}

public static string IsActive(this HtmlHelper helper, string action, string controllerName, string output)
{
    var currentController =  helper.ViewContext.RouteData.Values["controller"].ToString();
    var currentAction = helper.ViewContext.RouteData.Values["action"].ToString();

    return (currentController == controllerName && action == currentAction) ? output : string.Empty;
}

And here is what the view code looks like. Notice that I declare my output as a constant string in the view. I chose to do this in case I chose to change my html. I also didn’t want html to sneak into my helpers and thought this was a good alternative to that.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%@ Import Namespace="AquaBird.MainSite.Infrastructure.Extensions"%>
<%const string output = " id=\"active\""; %>
  <ul>
    <li<%=Html.IsActive("Index", "Home", output)%>>
        <a href="<%=Url.Action("Index", "Home") %>"><span><Home</span></a>
    </li>
    <li<%=Html.IsActive("About", "Home", output) %>>
        <a href="<%=Url.Action("About", "Home") %>"><span>Company</span></a>
    </li>
    <li<%=Html.IsActive("Services", output) %>>
        <a href="<%=Url.Action("Index","Services") %>"><span>Services</span></a>
    </li>
    <li<%=Html.IsActive("Portfolio", output) %>>
        <a href="<%=Url.Action("Index", "Portfolio") %>"><span>Portfolio</a>
    </li>
    <li<%=Html.IsActive("Products", output) %>>
        <a href="<%=Url.Action("Index", "Products") %>"><span>Products</a>
    </li>
    <li<%=Html.IsActive("Contact", output) %>>
        <a href="<%=Url.Action("Index", "Contact") %>"><span>Contact</a>
    </li>
  </ul>

There you have it. Now you can know whether you are on a certain controller and action from your view without breaking the rules of MVC.

P.S. Having multiple elements on the same page with the same id will make your page invalid when run through a HTML validator, keep that in mind.