Active links on Bootstrap Navbar with ASP.NET MVC

If you have used Bootstrap with your ASP.NET MVC application, you might have faced some issues with implementing active links of it’s Navbar component. We’ll have to dynamically add a css class called active to the particular menu item in order to make it selected in the Navbar. Here is a HtmlHelper extension which is capable of rendering menu items as well as drop-down menu items. I’ve used ASP.NET MVC 5 with Razor and Bootstrap 3.

First step is to create a HtmlHelper extension class. 

using System.Web.Mvc;

public static class MenuLinkExtension
{
    public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string itemText, string actionName, string controllerName, MvcHtmlString[] childElements = null)
    {
        var currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
        var currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
        string finalHtml;
        var linkBuilder = new TagBuilder("a");
        var liBuilder = new TagBuilder("li");

        if (childElements != null && childElements.Length > 0)
        {
            linkBuilder.MergeAttribute("href", "#");
            linkBuilder.AddCssClass("dropdown-toggle");
            linkBuilder.InnerHtml = itemText + " <b class=\"caret\"></b>";
            linkBuilder.MergeAttribute("data-toggle", "dropdown");
            var ulBuilder = new TagBuilder("ul");
            ulBuilder.AddCssClass("dropdown-menu");
            ulBuilder.MergeAttribute("role", "menu");
            foreach (var item in childElements)
            {
                ulBuilder.InnerHtml += item + "\n";
            }

            liBuilder.InnerHtml = linkBuilder + "\n" + ulBuilder;
            liBuilder.AddCssClass("dropdown");
            if (controllerName == currentController)
            {
                liBuilder.AddCssClass("active");
            }

            finalHtml = liBuilder.ToString() + ulBuilder;
        }
        else
        {
            var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
            linkBuilder.MergeAttribute("href", urlHelper.Action(actionName, controllerName));
            linkBuilder.SetInnerText(itemText);
            liBuilder.InnerHtml = linkBuilder.ToString();
            if (controllerName == currentController && actionName == currentAction)
            {
                liBuilder.AddCssClass("active");
            }

            finalHtml = liBuilder.ToString();
        }

        return new MvcHtmlString(finalHtml);
    }
}

Once you have saved it, you can it by just calling like this!

<header class="navbar navbar-inverse navbar-fixed-top bs-docs-nav" role="banner">
    <div class="container">
        <div class="navbar-header">
            <a href="#" class="navbar-brand">Mvc Shop</a>
        </div>
        <nav role="navigation">
 
            <ul class="nav navbar-nav">
                @Html.MenuLink("Home", "Index", "Home")
                @Html.MenuLink("Dropdown", "Index", "Home2", new MvcHtmlString[]{
                                      @Html.MenuLink("Link1", "Action1", "Controller1"),
                                      @Html.MenuLink("Link2", "Action2", "Controller1"),
                                      @Html.MenuLink("Link3", "Action3", "Controller1"),
                                    })
                @Html.MenuLink("JavaScript", "Index", "Home1", new MvcHtmlString[]{
                                      @Html.MenuLink("Link1", "Index1", "Home1"),
                                      @Html.MenuLink("Link2", "Index2", "Home1"),
                                      @Html.MenuLink("Link3", "Index3", "Home1")
                                    })
 
            </ul>
        </nav>
    </div>
</header>