You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 2中如何判断当前菜单并动态设置激活状态

嘿,这个问题我在ASP.NET Core 2的项目里折腾过好几次,给你分享几个实用的解决办法,帮你搞定导航栏的激活状态:

方法1:直接利用ViewContext获取当前路由(最省心的基础方案)

这个方法不需要额外写复杂代码,直接通过ViewContext拿到当前请求的控制器和动作名称,然后对比判断即可。

首先在你的_NavBar.cshtml分部视图里,先获取当前路由信息:

@{
    // 从路由数据里提取当前控制器和动作,为空时设为空字符串避免报错
    var currentController = ViewContext.RouteData.Values["Controller"]?.ToString() ?? "";
    var currentAction = ViewContext.RouteData.Values["Action"]?.ToString() ?? "";
}

然后在导航项里添加判断逻辑,动态设置active类:

<ul class="nav navbar-nav">
    <li class="@(currentController.Equals("Home", StringComparison.OrdinalIgnoreCase) && currentAction.Equals("Index", StringComparison.OrdinalIgnoreCase) ? "active" : "")">
        <a asp-controller="Home" asp-action="Index">首页</a>
    </li>
    <li class="@(currentController.Equals("About", StringComparison.OrdinalIgnoreCase) && currentAction.Equals("Index", StringComparison.OrdinalIgnoreCase) ? "active" : "")">
        <a asp-controller="About" asp-action="Index">关于页</a>
    </li>
    <li class="@(currentController.Equals("Contact", StringComparison.OrdinalIgnoreCase) && currentAction.Equals("Index", StringComparison.OrdinalIgnoreCase) ? "active" : "")">
        <a asp-controller="Contact" asp-action="Index">联系页</a>
    </li>
</ul>

这里用OrdinalIgnoreCase是为了避免大小写敏感的问题,比如控制器名称如果是home也能匹配上。

方法2:自定义Tag Helper(更优雅的可复用方案)

如果觉得每个导航项都写三元运算符太啰嗦,可以自定义一个Tag Helper来简化代码,以后新增导航项也更方便。

步骤1:创建ActiveTagHelper类

在项目里新建一个类(比如放在TagHelpers文件夹下):

using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Http;

[HtmlTargetElement("li", Attributes = "asp-active-controller, asp-active-action")]
public class ActiveTagHelper : TagHelper
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    // 通过依赖注入获取HttpContextAccessor
    public ActiveTagHelper(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    // 接收传入的控制器名称
    [HtmlAttributeName("asp-active-controller")]
    public string TargetController { get; set; }

    // 接收传入的动作名称
    [HtmlAttributeName("asp-active-action")]
    public string TargetAction { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        var currentRoute = _httpContextAccessor.HttpContext.Request.RouteValues;
        var currentController = currentRoute["Controller"]?.ToString() ?? "";
        var currentAction = currentRoute["Action"]?.ToString() ?? "";

        // 对比当前路由和目标路由,匹配的话添加active类
        if (currentController.Equals(TargetController, StringComparison.OrdinalIgnoreCase) &&
            currentAction.Equals(TargetAction, StringComparison.OrdinalIgnoreCase))
        {
            var existingClass = output.Attributes["class"]?.Value.ToString() ?? "";
            output.Attributes.SetAttribute("class", $"{existingClass} active".Trim());
        }

        base.Process(context, output);
    }
}

步骤2:注册Tag Helper

在_ViewImports.cshtml里添加注册代码,把你的项目命名空间替换进去:

@addTagHelper *, YourProjectNameSpace

步骤3:在_NavBar里使用

现在导航项的代码就简洁多了:

<ul class="nav navbar-nav">
    <li asp-active-controller="Home" asp-active-action="Index">
        <a asp-controller="Home" asp-action="Index">首页</a>
    </li>
    <li asp-active-controller="About" asp-active-action="Index">
        <a asp-controller="About" asp-action="Index">关于页</a>
    </li>
    <li asp-active-controller="Contact" asp-active-action="Index">
        <a asp-controller="Contact" asp-action="Index">联系页</a>
    </li>
</ul>
方法3:用ViewBag传递激活状态(适合小型项目)

如果你的项目页面很少,也可以在每个控制器的Action里手动设置ViewBag,然后在分部视图里判断:

比如在HomeController的Index方法里:

public IActionResult Index()
{
    ViewBag.ActiveMenu = "Home";
    return View();
}

AboutController的Index方法:

public IActionResult Index()
{
    ViewBag.ActiveMenu = "About";
    return View();
}

然后_NavBar.cshtml里:

<ul class="nav navbar-nav">
    <li class="@(ViewBag.ActiveMenu == "Home" ? "active" : "")">
        <a asp-controller="Home" asp-action="Index">首页</a>
    </li>
    <li class="@(ViewBag.ActiveMenu == "About" ? "active" : "")">
        <a asp-controller="About" asp-action="Index">关于页</a>
    </li>
    <li class="@(ViewBag.ActiveMenu == "Contact" ? "active" : "")">
        <a asp-controller="Contact" asp-action="Index">联系页</a>
    </li>
</ul>

这个方法简单,但缺点是每个Action都要写一遍,不够灵活,适合页面不多的小型项目。


内容的提问来源于stack exchange,提问作者user9248102

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:23:14