ASP.NET Core MVC中如何全局初始化共享视图所需变量?
解决方案
方案1:使用ViewComponent(推荐)
这是ASP.NET Core中处理全局复用视图片段的最优方案,无需修改任何现有控制器,完全适配导航栏这类场景。
实现步骤:
- 创建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); } }
- 创建对应视图文件
在Views/Shared/Components/PostCategories/Default.cshtml路径下创建视图:
@model List<PostCategoryModel> <!-- 替换为你的下拉菜单HTML结构 --> <select> @foreach(var category in Model) { <option value="@category.Id">@category.Name</option> } </select>
- 在共享Navbar视图中调用组件
@await Component.InvokeAsync("PostCategories")
方案2:全局Action Filter
通过全局过滤器,在所有Action执行后自动注入分类数据到ViewData/ViewBag,让所有视图(包括共享视图)都能访问。
实现步骤:
- 创建异步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; } } }
- 在Program.cs注册全局过滤器
builder.Services.AddControllersWithViews(options => { options.Filters.Add<InjectPostCategoriesFilter>(); });
- 在共享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
相关产品推荐
相关产品推荐

