如何在ASP.NET MVC中将“活动”类添加到Html.ActionLink

我想添加一个“活跃”的类到我的启动navbar在MVC,但下面不显示活跃的类,当这样写:

<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> 

这解决了什么看起来像格式正确的类,但不起作用:

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

在Bootstrap文档中,它指出'a'标签不应该在导航栏中使用,但上面是我相信是向Html.ActionLink添加类的正确方法。 有另一种(整齐)的方式,我可以做到这一点?

我在学习ASP.NET MVC的早期阶段,所以我很抱歉如果我错过了一些明显的东西!

在Bootstrap中, active类需要应用于<li>元素而不是<a> 。 看到这里的第一个例子: http : //getbootstrap.com/components/#navbar

您处理基于活动或不活动的UI样式的方式与ASP.NET MVC的ActionLink帮助器无关。 这是跟随如何构buildBootstrap框架的正确解决scheme。

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

编辑:

由于您很可能会在多个页面上重复使用菜单,因此有一种方法可以根据当前页面自动应用所选类别,而不是多次复制菜单并手动执行。

最简单的方法是简单地使用ViewContext.RouteData包含的值,即ActionController值。 我们可以build立在你现在拥有的东西上:

 <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> 

这在代码中并不漂亮,但它会完成工作,并允许您将菜单提取为局部视图(如果您喜欢的话)。 有办法以更清洁的方式来做到这一点,但是因为你刚刚开始,我会离开它。 祝好运学习ASP.NET MVC!


晚编辑:

这个问题似乎越来越stream量,所以我想我会抛出一个更优雅的解决scheme,使用HtmlHelper扩展。

编辑03-24-2015:不得不重写这个方法,以允许多个动作和控制器触发选定的行为,以及处理方法从一个子行动部分视图调用,认为我会分享更新!

 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> 

延期:

 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> 

我pipe理通过在asp.net mvc中添加一个视图包参数来做到这一点。 在这里,我做了什么

增加了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> 

这解决了我的问题。

我知道这个问题很老,但我只想在这里加上我的声音。 我相信这是一个好主意,让一个链接是否活跃的知识视图的控制器。

我只是为控制器操作中的每个视图设置一个唯一的值。 例如,如果我想让主页链接处于活动状态,我会这样做:

 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> 

当你导航到不同的页面时,说程序,ViewBag.Home不存在(而不是ViewBag.Programs); 因此,什么都没有呈现,甚至没有class =“”。 我认为这对于可维护性和清洁来说都是更清洁的。 我总是希望尽可能地把逻辑放在视图之外。

添加“.ToString”来改善ASP.NET MVC的比较

 <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> 

可能会迟到一点。 但希望这有助于。

 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" : ""; } } 

用法如下:

 <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> 

http://www.codingeverything.com/2014/05/mvcbootstrapactivenavbar.html获得参考;

你可以试试这个:在我的情况下,我从基于angular色访问的数据库中加载菜单,根据你的视图在你想要激活的菜单上编写代码。

 <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> 

@dombenoit的答案是有效的。 虽然它引入了一些代码来维护。 检查这个语法:

 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()方法。

如果你想知道什么使得这个语法成为可能,请查看TwitterBootstrapMVC

我修改了dom的 “不漂亮”的答案,并使其更丑。 有时两个控制器有冲突的行为名称(即索引),所以我这样做:

 <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> 

我意识到这个问题对于我们中的一些人来说是一个普遍的问题,所以我使用nuget包发布了我自己的解决scheme。 下面你可以看到它是如何工作的。 我希望这会有用。

注意:这个nuget包是我的第一个包。 所以,如果你看到一个错误,请给予反馈。 谢谢。

  1. 安装软件包或下载源代码并添加您的项目

     -Install-Package Betalgo.MvcMenuNavigator 
  2. 将您的页面添加到枚举

     public enum HeaderTop { Dashboard, Product } public enum HeaderSub { Index } 
  3. 将filter放置在您的Controllor或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(); } } 
  4. 并使用它在你的头部布局是这样的

     @{ 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> 

更多信息: https : //github.com/betalgo/MvcMenuNavigator

如果根本不显示,原因是你需要两个@符号:

 @@class 

但是,我相信你可能需要“li”标签上的活动类不在“a”标签上。 根据太bootstrap文档( 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> 

我们也可以从RequestContext创buildUrlHelper ,我们可以从MvcHandler本身获得。 因此,我相信一个想要在Razor模板中保留这个逻辑的人会有帮助:

  1. 在项目根目录下创build一个名为AppCode的文件夹。
  2. 在那里创build一个名为HtmlHelpers.cshtml的文件
  3. 在那里创build一个帮手:

     @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. 那么我们可以使用我们这样的看法:

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

希望对某人有帮助。

我也在寻找一个解决scheme和jQuery帮助非常多。 首先,你需要给你的<li>元素提供id。

 <li id="listguides"><a href='/Guides/List'>List Guides</a></li> 

在布局页面中完成后,可以告诉jQuery应该在视图中select<li>元素。

 @section Scripts{ <script type="text/javascript"> $('#listguides').addClass('selected'); </script> } 

注意:您需要在布局页面中使用@RenderSection("scripts", required: false) ,在</body>标记之前添加该部分。

希望这有助于,下面是你的菜单可以是:

  <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> 

并在html标签下添加下面的MVC帮助函数。

  @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; } } 

我提到了http://questionbox.in/add-active-class-menu-link-html-actionlink-asp-net-mvc/的答案;

我想提出这个解决scheme是基于Dom的答案的第一部分。

我们首先定义两个variables,“动作”和“控制器”,并使用它们来确定活动链接:

 { string controller = ViewContext.RouteData.Values["Controller"].ToString(); string action = ViewContext.RouteData.Values["Action"].ToString();} 

接着:

 <ul class="nav navbar-nav"> <li class="@((controller == "Home" && action == "Index") ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li> <li class="@((controller == "Home" && action == "About") ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li> <li class="@((controller == "Home" && action == "Contact") ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li> </ul> 

现在看起来更好,不需要更复杂的解决scheme。

我已经把上面的答案组合起来,并提出了解决scheme。

所以..

首先在剃刀块创build一个stringvariables,它将包含控制器的名称值和用户调用的操作。

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

然后使用HTML和Razor代码的组合:

  <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> 

我认为,这是好事,因为你不需要每次访问“ViewContext.RouteData.Values”来获取控制器名称和操作名称。

用lambda函数是可能的

 @{ string controllerAction = ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString(); Func<string, string> IsSelected= x => x==controllerAction ? "active" : ""; } 

然后用法

  @Html.ActionLink("Inicio", "Index", "Home", new { area = "" }, new { @class = IsSelected("HomeIndex")})