使用MVC&Ado.Net无法在模型中获取DropdownList值的求助
问题:MVC + ADO.NET中Post请求无法获取下拉框外键ID的解决方法
现有代码片段
1. 获取部门列表及Create Get方法
public List<Dept> GetDept() { connection(); List<Dept> deptList = new List<Dept>(); SqlCommand com = new SqlCommand("Sp_GetDept", con); com.CommandType = CommandType.StoredProcedure; SqlDataAdapter da = new SqlDataAdapter(com); DataTable dt = new DataTable(); con.Open(); da.Fill(dt); con.Close(); //Bind EmpModel generic list using dataRow foreach (DataRow dr in dt.Rows) { deptList.Add( new Dept { DeptId = Convert.ToInt32(dr["DeptId"]), Name = Convert.ToString(dr["Name"]) } ); } return deptList; } public ActionResult Create() { DeptRepo repo = new DeptRepo(); ViewBag.Dept = new SelectList(repo.GetDept(), "DeptId", "Name"); return View(); }
2. 视图代码
<div class="form-group"> @Html.LabelFor(model => model.Dept, "Department", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownList("Dept", null, "--Select--", htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Dept, "", new { @class = "text-danger" }) </div> </div>
3. Student模型
public class Student { public int StudentId { get; set; } public string Name { get; set; } public string Roll { get; set; } public int DeptId { get; set; } public virtual Dept Dept { get; set; } }
4. Post请求方法
[HttpPost] public ActionResult Create(Student std) { try { if (ModelState.IsValid) { StudentRepo repo = new StudentRepo(); repo.AddStudent(std); } return RedirectToAction("Index"); } catch { return View(); } }
问题分析
你遇到的核心问题是模型绑定不匹配:
- 视图里的下拉框命名为
"Dept",但Student模型中存储部门ID的属性是DeptId。MVC的模型绑定机制是根据表单字段的name属性匹配模型属性的,所以提交时系统找不到对应DeptId的字段值,导致它为null。 - 另外,
@Html.LabelFor(model => model.Dept)和@Html.ValidationMessageFor(model => model.Dept)绑定的是导航属性Dept,而非外键DeptId,这也会导致验证逻辑失效。
解决方案
我们需要调整ViewBag命名、下拉框名称及相关辅助方法,让它们和模型的DeptId属性匹配:
步骤1:修改Create Get方法的ViewBag命名
把ViewBag的键改为DeptId,直观对应模型属性:
public ActionResult Create() { DeptRepo repo = new DeptRepo(); ViewBag.DeptId = new SelectList(repo.GetDept(), "DeptId", "Name"); return View(); }
步骤2:修改视图代码,绑定到DeptId
推荐使用强类型的DropDownListFor,编译时即可检测拼写错误:
<div class="form-group"> @Html.LabelFor(model => model.DeptId, "Department", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownListFor(model => model.DeptId, (SelectList)ViewBag.DeptId, "--Select--", new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.DeptId, "", new { @class = "text-danger" }) </div> </div>
步骤3:添加模型验证(可选)
如果需要强制用户选择部门,给DeptId添加[Required]特性:
public class Student { public int StudentId { get; set; } public string Name { get; set; } public string Roll { get; set; } [Required(ErrorMessage = "请选择部门")] public int DeptId { get; set; } public virtual Dept Dept { get; set; } }
步骤4:完善Post方法的异常处理
如果Post请求失败返回视图,记得重新填充ViewBag的部门列表,避免下拉框空数据:
[HttpPost] public ActionResult Create(Student std) { try { if (ModelState.IsValid) { StudentRepo repo = new StudentRepo(); repo.AddStudent(std); return RedirectToAction("Index"); } } catch { // 可在此添加异常日志记录逻辑 } // 验证失败时重新填充部门列表 DeptRepo repo = new DeptRepo(); ViewBag.DeptId = new SelectList(repo.GetDept(), "DeptId", "Name"); return View(std); }
这样修改后,表单提交时MVC就能正确将下拉框选中的部门ID绑定到Student对象的DeptId属性中,你就能在Post方法里获取到这个外键值了。
内容的提问来源于stack exchange,提问作者Rasul005
相关产品推荐
相关产品推荐

