ASP.NET Core 6 MVC创建Idea时下拉框选中的Category返回Null问题
问题解决步骤
1. 清理Idea实体模型
Idea类中的IEnumerable<Category>? Categories属于冗余属性,它是用来填充下拉框的展示数据,不该放在业务实体模型里,直接移除即可。修正后的模型如下:
public class Idea { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } public string Rating { get; set; } public string Status { get; set; } public DateTime Date { get; set; } [ForeignKey(nameof(Category))] public int CategoryId { get; set; } public Category? Category { get; set; } }
2. 调整Post提交逻辑
表单提交时只会传递CategoryId,不会传递完整的Category对象,所以不需要给Category属性赋值。EF Core只需要外键ID就能关联到对应的分类数据,修改后的AddIdea方法:
[HttpPost] public async Task<IActionResult> AddIdea(Idea viewModel) { if (ModelState.IsValid) { var idea = new Idea { Name = viewModel.Name, Description = viewModel.Description, Rating = viewModel.Rating, Status = viewModel.Status, Date = viewModel.Date, CategoryId = viewModel.CategoryId // 仅需设置外键ID }; _ideaRepository.Add(idea); await _ideaRepository.SaveChangesAsync(); // 确保调用保存方法提交到数据库 return RedirectToAction("Index"); } // 验证失败时重新加载分类下拉框数据 var categories = await _categoryRepository.GetAllCategories(); ViewBag.Categories = new SelectList(categories, "Id", "Name"); return View(viewModel); }
3. 查询时显式加载关联的Category
当你在页面上需要显示Category.Name时,必须在查询Idea数据时显式加载关联的Category(EF Core默认不会自动加载关联实体)。在Repository的查询方法中添加Include:
public async Task<IEnumerable<Idea>> GetAllIdeas() { return await _context.Ideas.Include(i => i.Category).ToListAsync(); }
然后在控制器的Index方法中调用这个查询方法,确保传递给视图的Idea对象已经包含了Category数据。
4. 确认视图下拉框绑定正确
确保视图中的下拉框name属性为CategoryId,保证表单提交时能正确绑定到Idea的CategoryId属性:
<div class="form-group"> <label asp-for="CategoryId" class="control-label"></label> <select asp-for="CategoryId" asp-items="@ViewBag.Categories" class="form-control"></select> <span asp-validation-for="CategoryId" class="text-danger"></span> </div>
可选优化:使用专用ViewModel
如果想让代码更规范,建议创建专门的CreateIdeaViewModel来分离视图绑定和业务实体:
public class CreateIdeaViewModel { public string Name { get; set; } public string Description { get; set; } public string Rating { get; set; } public string Status { get; set; } public DateTime Date { get; set; } public int CategoryId { get; set; } public IEnumerable<SelectListItem> Categories { get; set; } }
在Get请求的AddIdea方法中初始化ViewModel并赋值Categories,Post方法接收ViewModel后再转换为Idea实体保存。
内容的提问来源于stack exchange,提问作者Tshifhiwa Nevhuhulwi
相关产品推荐
相关产品推荐

