How to add “active” class to Html.ActionLink in AS

2019-01-01 06:47发布

I'm trying to add an"active" class to my bootstrap navbar in MVC, but the following doesn't show the active class when written like this:

<ul class="nav navbar-nav">
  <li>@Html.ActionLink("Home", "Index", "Home", null, new {@class="active"})</li>
  <li>@Html.ActionLink("About", "About", "Home")</li>
  <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

This resolves to what looks like a correctly formatted class, but doesn't work:

<a class="active" href="/">Home</a>

In the Bootstrap documentation it states that 'a' tags shouldn't be used in the navbar, but the above is how I believe is the correct way of adding a class to an Html.ActionLink. Is there another (tidy) way I can do this?

21条回答
还给你的自由
2楼-- · 2019-01-01 06:56

My Solution to this problem is

<li class="@(Context.Request.Path.Value.ToLower().Contains("about") ? "active " : "" ) nav-item">
                <a class="nav-link" asp-area="" asp-controller="Home" asp-action="About">About</a>
            </li>

A better way may be adding an Html extension method to return the current path to be compared with link

查看更多
无与为乐者.
3楼-- · 2019-01-01 06:57

the answer by @dombenoit works. Though it introduces some code to maintain. Check this syntax out:

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", "#")
}

Notice the use of .SetLinksActiveByControllerAndAction() method.

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

查看更多
有味是清欢
4楼-- · 2019-01-01 06:57

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>

therefore your code will be:

<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>
查看更多
浮光初槿花落
5楼-- · 2019-01-01 06:57

Hope this helps, below is how your menu can be:

 <ul class="nav navbar-nav">
   <li><a href="@Url.Action("Index", "Home")" class="@IsMenuSelected("Index","Home", "active")">Home</a></li>
   <li><a href="@Url.Action("About", "Home")" class="@IsMenuSelected("About", "Home", "active")">About</a></li>
   <li><a href="@Url.Action("Contact", "Home")" class="@IsMenuSelected("Contact", "Home", "active")">Contact</a></li>
 </ul>

And add below MVC helper function below the html tag.

 @helper IsMenuSelected(string actionName, string controllerName, string className)
    {
            var conname = ViewContext.RouteData.Values["controller"].ToString().ToLower();
            var actname = ViewContext.RouteData.Values["action"].ToString().ToLower();

            if (conname == controllerName.ToLower() && actname == actionName.ToLower())
        {
            @className;
        }
    }

I referred the answer from http://questionbox.in/add-active-class-menu-link-html-actionlink-asp-net-mvc/

查看更多
怪性笑人.
6楼-- · 2019-01-01 06:57

I believe here is a cleaner and smalller code to do get the selected menu being "active":

 <ul class="navbar-nav mr-auto">
                <li class="nav-item @Html.IfSelected("Index")">
                    <a class="nav-link" href="@Url.Action("Index", "Home")">Home</a>
                </li>
                <li class="nav-item @Html.IfSelected("Controls")">
                    <a class="nav-link" href="@Url.Action("Controls", "Home")">MVC Controls</a>
                </li>
                <li class="nav-item @Html.IfSelected("About")">
                    <a class="nav-link" href="@Url.Action("About", "Home")">About</a>
                </li>
</ul>

 public static string IfSelected(this HtmlHelper html, string action)
        {
            return html
                       .ViewContext
                       .RouteData
                       .Values["action"]
                       .ToString() == action
                            ? " active"
                            : "";
        }
查看更多
低头抚发
7楼-- · 2019-01-01 06:58

We also can create UrlHelper from RequestContext which we can get from MvcHandler itself. Therefore I beleive for someone who wants to keep this logic in Razor templates following way would be helpful:

  1. In project root create a folder named AppCode.
  2. Create a file there named HtmlHelpers.cshtml
  3. Create a helper in there:

    @helper MenuItem(string action, string controller)
    {
         var mvcHandler = Context.CurrentHandler as MvcHandler;
         if (mvcHandler != null)
         {
             var url = new UrlHelper(mvcHandler.RequestContext);
             var routeData = mvcHandler.RequestContext.RouteData;
             var currentAction = routeData.Values["action"].ToString();
             var currentController = routeData.Values["controller"].ToString();
             var isCurrent = string.Equals(currentAction, action, StringComparison.InvariantCultureIgnoreCase) &&
                             string.Equals(currentController, controller, StringComparison.InvariantCultureIgnoreCase);
    
            <div class="@(isCurrent ? "active" : "")">
                <div>@url.Action(action, controller)</div>
            </div>
         }   
    }
    
  4. Then we can use on our views like this:

    @HtmlHelpers.MenuItem("Default", "Home")
    

Hope that it helps to someone.

查看更多
登录 后发表回答