ASP.NET Core 6.0 Razor Pages布局页动态菜单实现求助
ASP.NET Core 6.0 Razor Pages 动态导航菜单集成布局页实现方案
针对你遇到的数据库驱动动态菜单无法集成到布局页的问题,以下是几种无需依赖分部页的可行实现方案:
方案一:使用ViewComponent(推荐)
ViewComponent 是 Razor Pages 中用于复用带业务逻辑组件的最佳方式,它独立于页面模型,可直接在布局页中调用。
1. 创建ViewComponent类
在项目中新建类(例如 NavigationMenuViewComponent.cs),注入数据库上下文并获取菜单数据:
public class NavigationMenuViewComponent : ViewComponent { private readonly AppDbContext _dbContext; public NavigationMenuViewComponent(AppDbContext dbContext) { _dbContext = dbContext; } public async Task<IViewComponentResult> InvokeAsync() { // 从数据库查询激活状态的菜单,按排序号排序 var menuItems = await _dbContext.MenuItems .Where(m => m.IsActive) .OrderBy(m => m.SortOrder) .ToListAsync(); return View(menuItems); } }
2. 创建ViewComponent视图
在项目中创建路径 Pages/Shared/Components/NavigationMenu/Default.cshtml,编写菜单渲染逻辑:
<ul class="navbar-nav"> @foreach (var item in Model) { <li class="nav-item"> <a class="nav-link" asp-page="@item.PageUrl">@item.MenuText</a> </li> } </ul>
3. 在布局页中调用ViewComponent
打开布局页(_Layout.cshtml),在导航栏位置添加调用代码:
<div class="navbar-collapse collapse"> @await Component.InvokeAsync("NavigationMenu") </div>
方案二:基于PageModel基类共享数据
通过创建所有页面模型的基类,在基类中统一加载菜单数据,布局页直接使用基类的属性。
1. 创建基类PageModel
public class BasePageModel : PageModel { protected readonly AppDbContext _dbContext; public List<MenuItem> MenuItems { get; set; } = new(); public BasePageModel(AppDbContext dbContext) { _dbContext = dbContext; } public async Task LoadMenuAsync() { MenuItems = await _dbContext.MenuItems .Where(m => m.IsActive) .OrderBy(m => m.SortOrder) .ToListAsync(); } }
2. 所有页面模型继承基类
例如首页的PageModel:
public class IndexModel : BasePageModel { public IndexModel(AppDbContext dbContext) : base(dbContext) { } public async Task OnGetAsync() { await LoadMenuAsync(); // 页面自身业务逻辑 } }
3. 布局页中渲染菜单
直接通过模型属性访问菜单数据:
<ul class="navbar-nav"> @foreach (var item in Model.MenuItems) { <li class="nav-item"> <a class="nav-link" asp-page="@item.PageUrl">@item.MenuText</a> </li> } </ul>
方案三:自定义Tag Helper
通过自定义Tag Helper,直接在布局页中生成菜单HTML,适合需要高度自定义渲染逻辑的场景。
1. 创建Tag Helper类
[HtmlTargetElement("navigation-menu")] public class NavigationMenuTagHelper : TagHelper { private readonly AppDbContext _dbContext; private readonly IUrlHelperFactory _urlHelperFactory; private readonly ViewContext _viewContext; public NavigationMenuTagHelper(AppDbContext dbContext, IUrlHelperFactory urlHelperFactory, ViewContext viewContext) { _dbContext = dbContext; _urlHelperFactory = urlHelperFactory; _viewContext = viewContext; } public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var menuItems = await _dbContext.MenuItems .Where(m => m.IsActive) .OrderBy(m => m.SortOrder) .ToListAsync(); var urlHelper = _urlHelperFactory.GetUrlHelper(_viewContext); var sb = new StringBuilder(); sb.Append("<ul class='navbar-nav'>"); foreach (var item in menuItems) { var pageUrl = urlHelper.Page(item.PageUrl); sb.AppendFormat("<li class='nav-item'><a class='nav-link' href='{0}'>{1}</a></li>", pageUrl, item.MenuText); } sb.Append("</ul>"); output.Content.SetHtmlContent(sb.ToString()); } }
2. 注册Tag Helper
在 _ViewImports.cshtml 中添加Tag Helper命名空间:
@addTagHelper *, YourProjectAssemblyName
3. 布局页中使用自定义Tag
<navigation-menu></navigation-menu>
内容的提问来源于stack exchange,提问作者user19793054
相关产品推荐
相关产品推荐

