ASP.NET MVC中ViewBag绑定DropDownList空引用异常解决方法
问题根因
这个空引用报错基本都是以下几个高频问题导致的,按出现概率排序:
- POST提交表单的对应Action方法没有重新给下拉列表数据源赋值,ViewBag是单次请求生效的临时存储,GET请求里存的值不会保留到POST回发请求,回发时
ViewBag.BatimentList为null - GET请求返回视图时没有传入初始化的强类型模型实例,视图里的Model为null,执行
model => model.Batiment绑定逻辑时直接触发空引用,和ViewBag判空逻辑无关 - 视图里用强制类型转换
(SelectList)ViewBag.BatimentList,如果ViewBag值为null,强转本身就会抛异常 - 数据库上下文
_context未正确初始化,或Batiments类的Id_Batiment/Nom属性名拼写错误,导致SelectList创建失败
修复步骤
- 所有返回该视图的Action(包括GET和POST回发)都必须赋值下拉列表数据源,不要遗漏POST逻辑
错误POST示例(漏赋值):
[HttpPost] public ActionResult TableauPolyvalence(TableauPolyvalenceViewModel model) { if (ModelState.IsValid) { // 业务处理逻辑 return RedirectToAction("Index"); } // 此处未重新赋值ViewBag.BatimentList,直接返回视图必然报错 return View(model); }
正确POST写法:
[HttpPost] public ActionResult TableauPolyvalence(TableauPolyvalenceViewModel model) { if (ModelState.IsValid) { // 业务处理逻辑 return RedirectToAction("Index"); } // 只要返回当前视图,必须重新绑定下拉数据源 List<Batiments> BatimentList = _context.Batiments.ToList(); ViewBag.BatimentList = new SelectList(BatimentList, "Id_Batiment", "Nom"); return View(model); }
- GET Action返回视图时传入初始化好的模型实例,避免Model为null
public ActionResult TableauPolyvalence() { List<Batiments> BatimentList = _context.Batiments.ToList(); ViewBag.BatimentList = new SelectList(BatimentList, "Id_Batiment", "Nom"); // 初始化模型传入视图 var viewModel = new TableauPolyvalenceViewModel(); return View(viewModel); }
- 简化视图代码,用安全类型转换代替强制转换,避免转换异常
@model 你的项目命名空间.Models.TableauPolyvalenceViewModel @* 其他页面代码 *@ @Html.DropDownListFor( model => model.Batiment, ViewBag.BatimentList as SelectList, "-- Sélectionner le bâtiment --", new { @class = "form-control" } )
用
as SelectList做类型转换时,就算数据源为null也不会抛异常,DropDownListFor方法本身可以兼容null的数据源,不会触发空引用。
可选优化(推荐)
不要用ViewBag存下拉列表数据,容易出现键名拼写错误、漏赋值等问题,把数据源直接放到强类型ViewModel里,编译期就能检查错误:
首先定义ViewModel:
public class TableauPolyvalenceViewModel { // 绑定下拉选中值,如果是必填项去掉?改成int类型 public int? Batiment { get; set; } public SelectList BatimentList { get; set; } }
控制器赋值:
public ActionResult TableauPolyvalence() { var model = new TableauPolyvalenceViewModel(); List<Batiments> BatimentList = _context.Batiments.ToList(); model.BatimentList = new SelectList(BatimentList, "Id_Batiment", "Nom"); return View(model); } [HttpPost] public ActionResult TableauPolyvalence(TableauPolyvalenceViewModel model) { if (ModelState.IsValid) { // 业务处理逻辑 return RedirectToAction("Index"); } // 回发时重新给模型的下拉列表赋值 List<Batiments> BatimentList = _context.Batiments.ToList(); model.BatimentList = new SelectList(BatimentList, "Id_Batiment", "Nom"); return View(model); }
视图绑定:
@model 你的项目命名空间.Models.TableauPolyvalenceViewModel @Html.DropDownListFor( model => model.Batiment, Model.BatimentList, "-- Sélectionner le bâtiment --", new { @class = "form-control" } )
内容的提问来源于stack exchange,提问作者DimitriB
相关产品推荐
相关产品推荐

