ASP.NET Core MVC动态导航栏下拉菜单无法展开求助
在ASP.NET Core MVC中开发了基于用户角色的动态导航栏,通过数据库查询获取父级控制器与子级视图生成菜单结构,但下拉菜单无法展开显示子项,相关代码如下:
_Layout.cshtml 代码
<head> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> </head> <body> @if (HttpContextAccessor.HttpContext.Session.GetString("IsLoggedIn") == null) { <partial name="_NavBarBlank" /> } else { <partial name="_NavigationBar" /> } // 其他业务代码 <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> </body>
_NavigationBar.cshtml 代码
@inject IHttpContextAccessor HttpContextAccessor @{ SQLDB sQLDB = new SQLDB(); } <nav class="navbar navbar-expand-lg navbar-light bg-light"> <div class="container-fluid"> <a class="navbar-brand" href="#">YourAppName</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <!-- Home link --> <ul class="navbar-nav"> <li class="nav-item"> <a class="nav-link active" aria-current="page" href="#">Home</a> </li> </ul> @using Newtonsoft.Json; @inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor <ul class="navbar-nav"> @{ string Role = HttpContextAccessor.HttpContext.Session.GetString("Role"); var dataTableParent = sQLDB.CreateTable($"SELECT Controller, isDropdown FROM WMS_ParentNavbar WHERE ROLE = "+Role+" ORDER BY Priority ASC"); } @foreach (DataRow drParent in dataTableParent.Rows) { string controller = drParent["Controller"].ToString(); bool isDropdown = Convert.ToBoolean(drParent["isDropdown"]); var dataTableChild = sQLDB.CreateTable($"SELECT CN.Views FROM WMS_ParentNavbar PN INNER JOIN WMS_ChildNavbar CN on PN.ObjectID = CN.ObjectID WHERE CN.Controller = '" + controller + "' AND CN.Role = "+ Role ); <li class="nav-item @(isDropdown? "dropdown" : "")"> @if (!isDropdown) { <a class="nav-link" asp-controller="@controller" asp-action="Index">@controller</a> } else { <a class="nav-link dropdown-toggle" href="#" id="@controller" role="button" data-bs-toggle="dropdown" aria-expanded="false"> @controller </a> <div class="dropdown-menu" aria-labelledby="@controller"> @foreach (DataRow drChild in dataTableChild.Rows) { string viewName = drChild["Views"].ToString(); <a class="dropdown-item" asp-controller="@controller" asp-action="@viewName">@viewName</a> } </div> } </li> } </ul> </div> </div> </nav>
修复步骤
确保HTML ID合法:
控制器名称可能包含空格或特殊字符,导致id="@controller"生成的HTML ID不符合规范,无法被aria-labelledby正确匹配。修改触发按钮的ID和下拉菜单的aria-labelledby值,替换非法字符:<a class="nav-link dropdown-toggle" href="#" id="@controller.Replace(" ", "-")" role="button" data-bs-toggle="dropdown" aria-expanded="false"> @controller </a> <div class="dropdown-menu" aria-labelledby="@controller.Replace(" ", "-")">验证Bootstrap脚本加载状态:
打开浏览器开发者工具(F12),切换到「网络」标签,刷新页面检查bootstrap.bundle.min.js是否成功加载(HTTP状态码为200)。如果路径错误,调整为正确的文件路径,确保使用的是包含Popper.js的bootstrap.bundle.min.js(Bootstrap 5依赖Popper实现下拉功能)。检查下拉菜单结构完整性:
确认父<li>在isDropdown为true时已正确添加dropdown类,且<div class="dropdown-menu">与触发按钮<a class="dropdown-toggle">为同级元素,这是Bootstrap 5下拉菜单的必要结构。排查子项数据是否正确获取:
可添加调试代码确认dataTableChild是否返回子项数据:<div class="dropdown-menu" aria-labelledby="@controller.Replace(" ", "-")"> @if (dataTableChild.Rows.Count == 0) { <span class="dropdown-item-text">无子项</span> } else { @foreach (DataRow drChild in dataTableChild.Rows) { string viewName = drChild["Views"].ToString(); <a class="dropdown-item" asp-controller="@controller" asp-action="@viewName">@viewName</a> } } </div>移除不必要的jQuery依赖:
Bootstrap 5不再依赖jQuery,若加载的jQuery版本与Bootstrap存在冲突,可尝试注释掉<script src="~/lib/jquery/dist/jquery.min.js"></script>,仅保留bootstrap.bundle.min.js测试效果。
内容的提问来源于stack exchange,提问作者anony

