Rectangle 27 198

In Bootstrap the active class needs to be applied to the <li> element and not the <a>. See the first example here: http://getbootstrap.com/components/#navbar

The way you handle your UI style based on what is active or not has nothing to do with ASP.NET MVC's ActionLink helper. This is the proper solution to follow how the Bootstrap framework was built.

Since you will most likely be reusing your menu on multiple pages, it would be smart to have a way to apply that selected class automatically based on the current page rather than copy the menu multiple times and do it manually.

The easiest way is to simply use the values contained in ViewContext.RouteData, namely the Action and Controller values. We could build on what you currently have with something like this:

<ul class="nav navbar-nav">
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

It's not pretty in code, but it'll get the job done and allow you to extract your menu into a partial view if you like. There are ways to do this in a much cleaner way, but since you're just getting started I'll leave it at that. Best of luck learning ASP.NET MVC!

This question seems to be getting a bit of traffic so I figured I'd throw in a more elegant solution using an HtmlHelper extension.

Edit 03-24-2015: Had to rewrite this method to allow for multiple actions and controllers triggering the selected behavior, as well as handling for when the method is called from a child action partial view, thought I'd share the update!

public static string IsSelected(this HtmlHelper html, string controllers = "", string actions = "", string cssClass = "selected")
{
    ViewContext viewContext = html.ViewContext;
    bool isChildAction = viewContext.Controller.ControllerContext.IsChildAction;

    if (isChildAction)
        viewContext = html.ViewContext.ParentActionViewContext;

    RouteValueDictionary routeValues = viewContext.RouteData.Values;
    string currentAction = routeValues["action"].ToString();
    string currentController = routeValues["controller"].ToString();

    if (String.IsNullOrEmpty(actions))
        actions = currentAction;

    if (String.IsNullOrEmpty(controllers))
        controllers = currentController;

    string[] acceptedActions = actions.Trim().Split(',').Distinct().ToArray();
    string[] acceptedControllers = controllers.Trim().Split(',').Distinct().ToArray();

    return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
        cssClass : String.Empty;
}
<ul>
    <li class="@Html.IsSelected(actions: "Home", controllers: "Default")">
        <a href="@Url.Action("Home", "Default")">Home</a>
    </li>
    <li class="@Html.IsSelected(actions: "List,Detail", controllers: "Default")">
        <a href="@Url.Action("List", "Default")">List</a>
    </li>
</ul>

Thanks, as I mentioned this is how I had it originally, but I was hoping to have one method throughout my code of changing the "active" class between selected objects.

With regards to the first edit, it actually worked for the Index page only. Seems the reason is that when it was making the comparison, it failed as ViewContext.RouteData.Values["Action"] does not return a String type object (still don't know how it worked for the first page....). When I changed all ViewContext.RouteData.Values["Action"] to ViewContext.RouteData.Values["Action"].toString(), it worked for all pages. Might want to add this in your solution just in case someone experiences the same problem.

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 21

public static MvcHtmlString LiActionLink(this HtmlHelper html, string text, string action, string controller)
{
    var context = html.ViewContext;
    if (context.Controller.ControllerContext.IsChildAction)
        context = html.ViewContext.ParentActionViewContext;
    var routeValues = context.RouteData.Values;
    var currentAction = routeValues["action"].ToString();
    var currentController = routeValues["controller"].ToString();

    var str = String.Format("<li role=\"presentation\"{0}>{1}</li>",
        currentAction.Equals(action, StringComparison.InvariantCulture) &&
        currentController.Equals(controller, StringComparison.InvariantCulture) ?
        " class=\"active\"" :
        String.Empty, html.ActionLink(text, action, controller).ToHtmlString()
    );
    return new MvcHtmlString(str);
}
<ul class="nav navbar-nav">
    @Html.LiActionLink("About", "About", "Home")
    @Html.LiActionLink("Contact", "Contact", "Home")
</ul>

This is a beautifully efficient extension. Works perfectly and is quite elegant. Hats off to you, Prof! My only gripe is with the role="presentation", which is not at all appropriate for a primary navigational menu (john.foliot.ca/aria-hidden/#pr). An unordered list is very much an appropriate container for a related set of links, as it groups them together in a logical manner.

var str = String.Format("<li role=\"presentation\"{0}>{1}</li>", currentAction.toLower().Equals(action.toLower(), StringComparison.InvariantCulture) &&         currentController.toLower().Equals(controller.toLower(), StringComparison.InvariantCulture) ?   " class=\"active\"" :         String.Empty, html.ActionLink(text, action, controller).ToHtmlString()     );

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 11

I manged to do this by adding a view bag parameter in asp.net mvc. Here what have i done

ViewBag.Current = "Scheduler";
<ul class="nav navbar-nav">
     <li class="@(ViewBag.Current == "Scheduler" ? "active" : "") "><a href="@Url.Action("Index","Scheduler")" target="_self">Scheduler</a></li>
 </ul>

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 5

I know this question is old, but I will just like to add my voice here. I believe it is a good idea to leave the knowledge of whether or not a link is active to the controller of the view.

I would just set a unique value for each view in the controller action. For instance, if I wanted to make the home page link active, I would do something like this:

public ActionResult Index()
{            
    ViewBag.Title = "Home";
    ViewBag.Home = "class = active";
    return View();
}
<li @ViewBag.Home>@Html.ActionLink("Home", "Index", "Home", null, new { title = "Go home" })</li>

When you navigate to a different page, say Programs, ViewBag.Home does not exist (instead ViewBag.Programs does); therefore, nothing is rendered, not even class="". I think this is cleaner both for maintainability and cleanliness. I tend to always want to leave logic out of the view as much as I can.

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 3

public static class Utilities
{
    public static string IsActive(this HtmlHelper html, 
                                  string control,
                                  string action)
    {
        var routeData = html.ViewContext.RouteData;

        var routeAction = (string)routeData.Values["action"];
        var routeControl = (string)routeData.Values["controller"];

        // both must match
        var returnActive = control == routeControl &&
                           action == routeAction;

        return returnActive ? "active" : "";
    }
}

And usage as follow:

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li class='@Html.IsActive("Home", "Index")'>
            @Html.ActionLink("Home", "Index", "Home")
        </li>
        <li class='@Html.IsActive("Home", "About")'>
            @Html.ActionLink("About", "About", "Home")
        </li>
        <li class='@Html.IsActive("Home", "Contact")'>
            @Html.ActionLink("Contact", "Contact", "Home")
        </li>
    </ul>
</div>

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 2

<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>

This won't work if there are same action names in two different controllers. Test it out with Home and About controllers with Index action.

@functions {      public bool IsActive(string action, string controller)     {         var actionRoute = ViewContext.RouteData.Values["Action"].ToString();         var controlRoute = ViewContext.RouteData.Values["Controller"].ToString();           return controller.Equals(controlRoute)&& actionRoute.Equals(actionRoute);     }  }
<li class="@(IsActive("Index", "Home")? "active": "")">

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 2

You can try this: In my case i am loading menu from database based on role based access, Write the code on your every view which menu your want to active based on your view.

<script type="text/javascript">
        $(document).ready(function () {         
            $('li.active active-menu').removeClass('active active-menu');
            $('a[href="/MgtCustomer/Index"]').closest('li').addClass('active active-menu');
        });
</script>

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 1

I realized that this problem was a common problem for some of us, so I published my own solution using nuget package. Below you can see how it works. I hope that will be useful.

Install Package or download source code and add your Project

-Install-Package Betalgo.MvcMenuNavigator

Add your pages to an enum

public enum HeaderTop
{
    Dashboard,
    Product
}
public enum HeaderSub
{
    Index
}
  • Put Filter to top of your Controllor or Action [MenuNavigator(HeaderTop.Product, HeaderSub.Index)] public class ProductsController : Controller { public async Task<ActionResult> Index() { return View(); } [MenuNavigator(HeaderTop.Dashboard, HeaderSub.Index)] public async Task<ActionResult> Dashboard() { return View(); } }
  • And use it In your header layout like this @{ var headerTop = (HeaderTop?)MenuNavigatorPageDataNavigatorPageData.HeaderTop; var headerSub = (HeaderSub?)MenuNavigatorPageDataNavigatorPageData.HeaderSub; } <div class="nav-collapse collapse navbar-collapse navbar-responsive-collapse"> <ul class="nav navbar-nav"> <li class="@(headerTop==HeaderTop.Dashboard?"active selected open":"")"> <a href="@Url.Action("Index","Home")">Dashboard</a> </li> <li class="@(headerTop==HeaderTop.Product?"active selected open":"")"> <a href="@Url.Action("Index", "Products")">Products</a> </li> </ul>

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 1

using (var nav = Html.Bootstrap().Begin(new Nav().Style(NavType.NavBar).SetLinksActiveByControllerAndAction()))
{
    @nav.ActionLink("Link 1", "action1")
    @nav.ActionLink("Link 2", "action2")
    @nav.Link("External Link", "#")
}
.SetLinksActiveByControllerAndAction()

If you wonder what makes this syntax possible, check out TwitterBootstrapMVC

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 1

I modified dom's "not pretty" answer and made it uglier. Sometimes two controllers have the conflicting action names (i.e. Index) so I do this:

<ul class="nav navbar-nav">
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "HomeIndex" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "AboutIndex" ? "active" : "")">@Html.ActionLink("About", "Index", "About")</li>
  <li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "ContactHome" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 119

Yes, you can just add another parameter with object representing css class:

Html.ActionLink("Create New", "Create", CONTROLLERNAME, null, new { @class= "yourCSSclass"} )
Html.ActionLink(link text, action name, controller name, route values object, html attributes object)
Html.ActionLink(
"Create New",
"Create",
CONTROLLERNAME,
null,
new { @class= "yourCSSclass", @style= "width:100px; color: red;" }
)

Thanks for the great answers. But now I am confused because I see three different ways of doing this that all have different parameters. Can someone give me some idea which might be best. Thank you so much.

@Sango: First parameter is actual link text that will be shown. Second paramter is name of action. Third is name of a controller. Fourth is object containing route values (ie. object that you need to pass to the route/action) - you don't need this one in this case, so just make it 'null'. And the last one is htmlAttributes object that got properties like 'class' which adds provided string/s as a css class to your link. You can see more at already mentioned documentation. Just note, that the answer from Rhapsody doesnt work because of..

There is no "best". They are all overloads which point to the same underlying code for rendering an achor tag. Which overload to choose depends on what you need in the URL.

asp.net mvc - Can I add a class to an HTML.ActionLink in MVC3 - Stack ...

asp.net-mvc
Rectangle 27 1

Why don't you add a css class to the selected link server side (in the ActionLink)?

<div id="menulinks">
    @Html.ActionLink("Home","Index","Home" new {type="new task"}, new { @class = "mlnkactive" })
    @Html.ActionLink("Home","Index")
</div>

And then remove the class and add it to the new selected link client side? Like this:

$('#menulinks a').click(function(){
    $('#menulinks a').removeClass('mlnkactive');
    $(this).addClass('mlnkactive');
}

i want a generic solution. i have like 14 menu items..4 menu items point to the same page with different querystring..the problem is that in jquery href attribute returns the same string '/Home/' and skips the querystring part..all the anchors with the same path gets selected.i dont want to hardcode and check each anchor against the querystring or something. There should be some way to deal with it

asp.net mvc 3 - How to get MVC ActionLink Full Path in Jquery - Stack ...

jquery asp.net-mvc-3
Rectangle 27 0

Html.ActionLink("Link Name", 
                "ActionName",
                "ControllerName",
                null,
                new { @class = "myCssClass" }
                )

this doesn't give the resulting anchor tag a class but passing class as a parameter to the ActionName action.

asp.net mvc 3 - Add CSS class to Html.ActionLink - Stack Overflow

css asp.net-mvc-3 asp.net-mvc-views
Rectangle 27 0

if is it is not showing at all, the reason is that you need two @ sign:

@@class

BUT, I believe you might need to have the active class on the "li" tag not on the "a" tag. according too bootstrap docs (http://getbootstrap.com/components/#navbar-default):

<ul class="nav navbar-nav">
  <li class="active"><a href="#">Home</a></li>
  <li><a href="#">Profile</a></li>
  <li><a href="#">Messages</a></li>
</ul>
<ul class="nav navbar-nav">
  <li class="active">@Html.ActionLink("Home", "Index", "Home", null)</li>
  <li>@Html.ActionLink("About", "About", "Home")</li>
  <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

The @@class throws an error, I originally had your code example above, which works, but isn't exactly as Actionlinks "should" be?

edited. the @@ is not required. you have to put the class on the EA

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 0

I have make combination of answers above and made my solution.

First in razor block create one string variable which will contain name value of controller and action that is called by user.

@{
        string controllerAction =  ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString(); 
    }

Then use combination of HTML and Razor code:

<ul class="nav navbar-nav">
        <li class="@(controllerAction == "HomeIndex" ? "active" : "" )">@Html.ActionLink("Home", "Index", "Home")</li>
        <li class="@(controllerAction == "AboutIndex" ? "active" : "" )">@Html.ActionLink("About", "Index", "About")</li>
        <li class="@(controllerAction == "HomeContact" ? "active" : "" )">@Html.ActionLink("Contact", "Contact", "Home")</li>
    </ul>

I think, that this is good because you don't need to access "ViewContext.RouteData.Values" each time to get controller name and action name.

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 0

Create a static class, for example Utilitarios.cs.

  • Inside the Class create a static method: public static string IsLinkActive(this UrlHelper url, string action, string controller) { if (url.RequestContext.RouteData.Values["controller"].ToString() == controller && url.RequestContext.RouteData.Values["action"].ToString() == action) { return "active"; } return ""; }
  • call like this <ul class="sidebar-menu" data-widget="tree"> <li class="header">HEADER</li> <li class="@Url.IsLinkActive("Index", "Home")"> <a href="@Url.Action("Index", "Home")"><i class="fa fa-link"></i> <span>Home</span></a> </li> <li class="@Url.IsLinkActive("About", "Home")"> <a href="@Url.Action("About", "Home")"><i class="fa fa-link"></i><span>About</span></a> </li> </ul>

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 0

In Bootstrap the active class needs to be applied to the <li> element and not the <a>. See the first example here: http://getbootstrap.com/components/#navbar

The way you handle your UI style based on what is active or not has nothing to do with ASP.NET MVC's ActionLink helper. This is the proper solution to follow how the Bootstrap framework was built.

Since you will most likely be reusing your menu on multiple pages, it would be smart to have a way to apply that selected class automatically based on the current page rather than copy the menu multiple times and do it manually.

The easiest way is to simply use the values contained in ViewContext.RouteData, namely the Action and Controller values. We could build on what you currently have with something like this:

<ul class="nav navbar-nav">
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
    <li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

It's not pretty in code, but it'll get the job done and allow you to extract your menu into a partial view if you like. There are ways to do this in a much cleaner way, but since you're just getting started I'll leave it at that. Best of luck learning ASP.NET MVC!

This question seems to be getting a bit of traffic so I figured I'd throw in a more elegant solution using an HtmlHelper extension.

Edit 03-24-2015: Had to rewrite this method to allow for multiple actions and controllers triggering the selected behavior, as well as handling for when the method is called from a child action partial view, thought I'd share the update!

public static string IsSelected(this HtmlHelper html, string controllers = "", string actions = "", string cssClass = "selected")
{
    ViewContext viewContext = html.ViewContext;
    bool isChildAction = viewContext.Controller.ControllerContext.IsChildAction;

    if (isChildAction)
        viewContext = html.ViewContext.ParentActionViewContext;

    RouteValueDictionary routeValues = viewContext.RouteData.Values;
    string currentAction = routeValues["action"].ToString();
    string currentController = routeValues["controller"].ToString();

    if (String.IsNullOrEmpty(actions))
        actions = currentAction;

    if (String.IsNullOrEmpty(controllers))
        controllers = currentController;

    string[] acceptedActions = actions.Trim().Split(',').Distinct().ToArray();
    string[] acceptedControllers = controllers.Trim().Split(',').Distinct().ToArray();

    return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
        cssClass : String.Empty;
}
<ul>
    <li class="@Html.IsSelected(actions: "Home", controllers: "Default")">
        <a href="@Url.Action("Home", "Default")">Home</a>
    </li>
    <li class="@Html.IsSelected(actions: "List,Detail", controllers: "Default")">
        <a href="@Url.Action("List", "Default")">List</a>
    </li>
</ul>

Thanks, as I mentioned this is how I had it originally, but I was hoping to have one method throughout my code of changing the "active" class between selected objects.

With regards to the first edit, it actually worked for the Index page only. Seems the reason is that when it was making the comparison, it failed as ViewContext.RouteData.Values["Action"] does not return a String type object (still don't know how it worked for the first page....). When I changed all ViewContext.RouteData.Values["Action"] to ViewContext.RouteData.Values["Action"].toString(), it worked for all pages. Might want to add this in your solution just in case someone experiences the same problem.

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 0

using (var nav = Html.Bootstrap().Begin(new Nav().Style(NavType.NavBar).SetLinksActiveByControllerAndAction()))
{
    @nav.ActionLink("Link 1", "action1")
    @nav.ActionLink("Link 2", "action2")
    @nav.Link("External Link", "#")
}
.SetLinksActiveByControllerAndAction()

If you wonder what makes this syntax possible, check out TwitterBootstrapMVC

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap
Rectangle 27 0

You have to use the @ character, since class is a keyword in C#. Here's a link to the MSDN documentation: http://msdn.microsoft.com/en-us/library/dd492124(v=vs.108).aspx

@Html.ActionLink("Link Text", "ActionName", 
         new { controller = "MyController", id = 1 }, 
         new { @class = "my-class" })

I did have my arguments wrong, that was the issue. Thanks.

css - How do I add a class to an @Html.ActionLink? - Stack Overflow

css asp.net-mvc razor
Rectangle 27 0

public static MvcHtmlString LiActionLink(this HtmlHelper html, string text, string action, string controller)
{
    var context = html.ViewContext;
    if (context.Controller.ControllerContext.IsChildAction)
        context = html.ViewContext.ParentActionViewContext;
    var routeValues = context.RouteData.Values;
    var currentAction = routeValues["action"].ToString();
    var currentController = routeValues["controller"].ToString();

    var str = String.Format("<li role=\"presentation\"{0}>{1}</li>",
        currentAction.Equals(action, StringComparison.InvariantCulture) &&
        currentController.Equals(controller, StringComparison.InvariantCulture) ?
        " class=\"active\"" :
        String.Empty, html.ActionLink(text, action, controller).ToHtmlString()
    );
    return new MvcHtmlString(str);
}
<ul class="nav navbar-nav">
    @Html.LiActionLink("About", "About", "Home")
    @Html.LiActionLink("Contact", "Contact", "Home")
</ul>

This is a beautifully efficient extension. Works perfectly and is quite elegant. Hats off to you, Prof! My only gripe is with the role="presentation", which is not at all appropriate for a primary navigational menu (john.foliot.ca/aria-hidden/#pr). An unordered list is very much an appropriate container for a related set of links, as it groups them together in a logical manner.

var str = String.Format("<li role=\"presentation\"{0}>{1}</li>", currentAction.toLower().Equals(action.toLower(), StringComparison.InvariantCulture) &&         currentController.toLower().Equals(controller.toLower(), StringComparison.InvariantCulture) ?   " class=\"active\"" :         String.Empty, html.ActionLink(text, action, controller).ToHtmlString()     );

css - How to add "active" class to Html.ActionLink in ASP.NET MVC - St...

asp.net css asp.net-mvc twitter-bootstrap