ASP.NET Core中DropDownListFor引发InvalidOperationException错误如何解决?
解决ASP.NET Core InvalidOperationException异常:ViewData键'Id'类型不匹配
问题原因
表单提交后ModelState验证失败,执行return View(obj)时未重新填充下拉框数据源。此时Razor视图会优先从ViewData中匹配下拉框的数据源参数,由于视图绑定表达式是Ders=>Ders.Id,框架会尝试读取键为"Id"的ViewData项——而此时Model的Id是int类型,并非下拉框所需的IEnumerable<SelectListItem>集合,因此抛出类型不匹配异常。
解决方案
1. 重构Controller:复用下拉框数据源生成逻辑
将生成下拉选项的代码抽成私有方法,在Get请求和Post验证失败时都调用该方法填充ViewBag,确保视图始终能获取到正确类型的数据源。
修改后的Controller代码:
// 抽出生成课程下拉选项的复用方法 private void LoadDersSelectItems() { var dersItems = _db.Dersler.Select(d => new SelectListItem { Text = d.DersName, Value = d.Id.ToString() }).ToList(); ViewBag.v1 = dersItems; } public IActionResult Create() { LoadDersSelectItems(); return View(); } [HttpPost] [ValidateAntiForgeryToken] public IActionResult Create(Ogretmen obj) { if (ModelState.IsValid) { _db.Ogretmenler.Add(obj); _db.SaveChanges(); return RedirectToAction("Index"); } // 验证失败时重新加载下拉选项 LoadDersSelectItems(); return View(obj); }
2. 优化视图(可选):使用ASP.NET Core Tag Helper
推荐用Tag Helper替代Html.DropDownListFor,语法更简洁直观,避免强制类型转换:
<div class="mb-3"> <h6>Ders Seçiniz</h6> <select asp-for="Id" asp-items="@ViewBag.v1" class="form-control"></select> </div>
核心总结
异常本质是Post请求验证失败返回视图时,下拉框数据源未重新初始化,导致框架错误地将Model的Id属性当作下拉数据源。通过在返回View前重新填充ViewBag中的下拉选项集合,即可解决类型不匹配问题。
内容的提问来源于stack exchange,提问作者aidasu
相关产品推荐
相关产品推荐

