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

ASP.NET Core MVC中如何全局初始化共享视图所需变量?

解决方案

方案1:使用ViewComponent(推荐)

这是ASP.NET Core中处理全局复用视图片段的最优方案,无需修改任何现有控制器,完全适配导航栏这类场景。

实现步骤:

  1. 创建ViewComponent类
public class PostCategoriesViewComponent : ViewComponent
{
    private readonly YourDbContext _context;

    // 通过依赖注入获取数据库上下文
    public PostCategoriesViewComponent(YourDbContext context)
    {
        _context = context;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        var categories = await _context.PostCategories.ToListAsync();
        return View(categories);
    }
}
  1. 创建对应视图文件
    在Views/Shared/Components/PostCategories/Default.cshtml路径下创建视图:
@model List<PostCategoryModel>

<!-- 替换为你的下拉菜单HTML结构 -->
<select>
    @foreach(var category in Model)
    {
        <option value="@category.Id">@category.Name</option>
    }
</select>
  1. 在共享Navbar视图中调用组件
@await Component.InvokeAsync("PostCategories")

方案2:全局Action Filter

通过全局过滤器,在所有Action执行后自动注入分类数据到ViewData/ViewBag,让所有视图(包括共享视图)都能访问。

实现步骤:

  1. 创建异步Action Filter
public class InjectPostCategoriesFilter : IAsyncActionFilter
{
    private readonly YourDbContext _context;

    public InjectPostCategoriesFilter(YourDbContext context)
    {
        _context = context;
    }

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // 先执行Action逻辑
        var resultContext = await next();

        // 仅当Action返回视图结果时注入数据
        if (resultContext.Result is ViewResult viewResult)
        {
            var categories = await _context.PostCategories.ToListAsync();
            viewResult.ViewData["PostCategories"] = categories;
        }
    }
}
  1. 在Program.cs注册全局过滤器
builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<InjectPostCategoriesFilter>();
});
  1. 在共享Navbar视图中使用数据
@{
    var categories = ViewData["PostCategories"] as List<PostCategoryModel>;
}

@if(categories != null)
{
    <select>
        @foreach(var category in categories)
        {
            <option value="@category.Id">@category.Name</option>
        }
    </select>
}

方案3:结合缓存优化性能(可选)

如果分类数据不频繁更新,可以用缓存减少数据库查询次数,以ViewComponent为例改造:

public class PostCategoriesViewComponent : ViewComponent
{
    private readonly YourDbContext _context;
    private readonly IMemoryCache _cache;
    private const string CacheKey = "PostCategories";

    public PostCategoriesViewComponent(YourDbContext context, IMemoryCache cache)
    {
        _context = context;
        _cache = cache;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        var categories = await _cache.GetOrCreateAsync(CacheKey, async entry =>
        {
            // 设置缓存过期时间,例如1小时
            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);
            return await _context.PostCategories.ToListAsync();
        });

        return View(categories);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:15:13