IEnumerable SelectListItem抛出ArgumentNullException:参数source不能为null如何排查
问题根因定位
从异常堆栈可以直接锁定错误位置:Checklist.Extensions.IEnumerableExtension.ToSelectListItem 方法执行时,传入的第一个参数 items 为 null,对应你视图里的调用逻辑是 Model.Customer.ToSelectListItem(Model.Checklists.CustomerId),也就是 Model.Customer 为空触发了空参数异常。
你之前误以为是 Model.Checklists.CustomerId 为空,实际上这个属性是值类型 int,本身不可能为 null,就算未赋值默认也为 0,不会触发本次的 ArgumentNullException。
突然报错的常见原因
你提到很久没修改相关代码突然出现问题,90% 以上的概率是 CreatePOST 方法的返回逻辑存在疏漏:
当表单提交后 ModelState.IsValid 为 false 时,你直接 return View(ChecklistVM),但 [BindProperty] 只会绑定表单提交过来的字段,原本从数据库加载的 Customer、CustomerSite、User 这类下拉列表数据源不会被前端提交,所以返回视图时 Model.Customer 就是 null,调用扩展方法就会抛异常。
小概率原因是数据库连接异常、Customer 表权限配置变动、表被清空导致 _db.Customer 查询返回 null。
修复方案
- 先给扩展方法加空值防护,从根源避免同类问题:
public static IEnumerable<SelectListItem> ToSelectListItem<T>(this IEnumerable<T> items, int selectedValue) { // 空输入直接返回空列表,不抛异常 items ??= Enumerable.Empty<T>(); return from item in items select new SelectListItem { Text = item.GetPropertyValue("Name"), Value = item.GetPropertyValue("Id"), Selected = item.GetPropertyValue("Id").Equals(selectedValue.ToString()) }; }
- 修复 POST 方法返回视图的逻辑,每次返回前重新加载所有下拉数据源:
if (!ModelState.IsValid) { // 重新赋值所有下拉列表的数据源 ChecklistVM.Customer = _db.Customer; ChecklistVM.CustomerSite = _db.CustomerSite; ChecklistVM.User = _db.IdentityUser; return View(ChecklistVM); }
- 可选优化:视图中
asp-for属性不需要加@前缀,规范写法为asp-for="Checklists.CustomerId",避免后续出现不必要的绑定问题。
内容的提问来源于stack exchange,提问作者Dein
相关产品推荐
相关产品推荐

