如何解决ASP.NET MVC Edit方法调用@Html.DropDownListFor的ViewData报错
问题原因
你的报错触发在POST提交Edit表单后渲染视图的场景,所有POST方法中返回View的分支都没有给ViewBag.RolesList赋值,视图渲染@Html.DropDownListFor时找不到对应的下拉选项数据源,就抛出了该异常。GET请求进入Edit页时你给ViewBag.RolesList赋了值,所以首次进编辑页是正常的。
修复方案
1. 抽离公共的下拉选项绑定方法
将生成角色下拉列表的逻辑抽为控制器私有方法,避免GET/POST分支重复编写代码:
// 放在EmployeeController类内 private void BindRolesDropdown() { AuthDBHandle dbhandle = new AuthDBHandle(); var roles = dbhandle.GetRoles(); ViewBag.RolesList = new SelectList(roles, "roles_id", "roles"); }
2. 优化GET Edit方法
去掉重复查询员工数据的冗余逻辑,同时不需要手动给SelectList传选中值,DropDownListFor会自动读取Model的roles_id作为选中项:
// GET: Employee/Edit/{id} public ActionResult Edit(int id) { adminlteDBHandle sdb = new adminlteDBHandle(); var employee = sdb.GetEmployee().Find(smodel => smodel.employee_id == id); if (employee == null) { return HttpNotFound(); } BindRolesDropdown(); return View(employee); }
3. 修改POST Edit方法
所有返回视图的分支都先绑定下拉数据源,同时返回用户提交的Model保留表单填写内容:
// POST: Employee/Edit/{id} [HttpPost] public ActionResult Edit(EmployeeViewModel smodel) { try { if (ModelState.IsValid) { adminlteDBHandle sdb = new adminlteDBHandle(); if (sdb.EditEmployee(smodel)) { return RedirectToAction("Index"); } } BindRolesDropdown(); return View(smodel); } catch { BindRolesDropdown(); return View(smodel); } }
修改完成后所有场景下视图渲染时都能拿到下拉数据源,报错就会消失。
内容的提问来源于stack exchange,提问作者Frank Andrew
相关产品推荐
相关产品推荐

