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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:50:25