.NET Core中通过分部视图传下拉列表,非首页路由失效问题解决
问题原因
你遇到的问题核心是:_Layout.cshtml 全局引用了分部视图,但只有 Home/Index 这个Action给 ViewBag.Proj 赋值了。当访问其他控制器的Action时,这些Action没有设置 ViewBag.Proj,分部视图渲染时找不到这个变量,直接抛出异常导致网站无法运行。
解决方案
推荐用两种方式解决,优先选第一种(视图组件),因为它是ASP.NET Core官方推荐的复用带逻辑视图的方案,独立性更强:
方案1:使用视图组件(View Component)
视图组件自带独立的业务逻辑,不需要依赖父Action的ViewBag,完全独立生成下拉列表所需的数据。
步骤1:创建视图组件类
在项目中新建一个类(比如放在ViewComponents文件夹下):
public class ProjectDropdownViewComponent : ViewComponent { private readonly YourDbContext _db; // 替换成你的DbContext类名 // 构造函数注入DbContext public ProjectDropdownViewComponent(YourDbContext db) { _db = db; } public async Task<IViewComponentResult> InvokeAsync() { // 查询项目列表,生成SelectList var projects = await _db.Projects.ToListAsync(); var projectSelectList = new SelectList(projects, "ProjectId", "ProjectName"); return View(projectSelectList); } }
步骤2:创建视图组件对应的分部视图
在Views/Shared/Components目录下,新建ProjectDropdown文件夹,里面创建Default.cshtml:
@model SelectList <!-- 这里写你的下拉列表HTML,示例如下 --> <select id="projectDropdown" class="form-control"> <option value="">请选择项目</option> @foreach (var item in Model) { <option value="@item.Value">@item.Text</option> } </select>
步骤3:在_Layout中调用视图组件
把原来的PartialAsync调用替换成视图组件调用:
@await Component.InvokeAsync("ProjectDropdown")
这样不管访问哪个控制器的Action,视图组件都会自己查询数据生成下拉列表,不会再出现空引用问题。
方案2:使用基础控制器统一赋值
如果不想用视图组件,可以创建一个基础控制器,让所有控制器继承它,在基础控制器的OnActionExecuting方法中统一给ViewBag.Proj赋值,这样所有Action都会自动带上这个变量。
步骤1:创建基础控制器
public class BaseController : Controller { protected readonly YourDbContext _db; public BaseController(YourDbContext db) { _db = db; } public override void OnActionExecuting(ActionExecutingContext context) { // 每次Action执行前都给ViewBag.Proj赋值 ViewBag.Proj = new SelectList(_db.Projects.ToList(), "ProjectId", "ProjectName"); base.OnActionExecuting(context); } }
步骤2:让所有控制器继承基础控制器
比如Home控制器:
public class HomeController : BaseController { public HomeController(YourDbContext db) : base(db) { } public IActionResult Index() { // 这里不需要再设置ViewBag.Proj了,基础控制器已经处理 return View(); } }
其他控制器也一样,都继承BaseController,这样所有视图(包括_Layout引用的分部视图)都能拿到ViewBag.Proj。
内容的提问来源于stack exchange,提问作者Rezo
相关产品推荐
相关产品推荐

