You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core传SelectList到视图报ArgumentNullException异常排查

下拉列表传值触发ArgumentNullException问题排查

报错信息

处理请求时发生未处理的异常。
ArgumentNullException: 值不能为 null。(参数 'items')
抛出位置为Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList..ctor(IEnumerable items, string dataValueField, string dataTextField, IEnumerable selectedValues, string dataGroupField)

相关代码

报错场景控制器代码

DataSet rolelist = _userService.GetUserRole();
List<SelectListItem> listo = new List<SelectListItem>();
foreach (DataRow dr in rolelist.Tables[0].Rows)
{
    listo.Add(new SelectListItem { 
        Text = dr["user_role_name"].ToString(),
        Value = dr["user_role_Id"].ToString() });
}
ViewBag.urolelist = listo;

视图代码

<div class="form-group">
    <label asp-for="Rolename" class="control-label"></label>
    <select asp-for="Rolename" class="form-control" asp-items="@(new SelectList(ViewBag.urolelist,"Value","Text"))"></select>
    <span asp-validation-for="Rolename" class="text-danger"></span>
</div>

仓储层查询代码

public DataSet GetUserRole()
{
    try
    {
        using (con = new SqlConnection(Constr))
        {
            con.Open();
            var cmd = new SqlCommand("GetUserRoleso", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataAdapter sqlData = new SqlDataAdapter(cmd);
            DataSet ds = new DataSet();
            sqlData.Fill(ds);
            return ds;
        }
    }
    catch (Exception ex)
    {
        throw;
    }
}

正常运行的GET Action代码

DataSet rolelist = _userService.GetUserRole();
List<SelectListItem> listo = new List<SelectListItem>();
foreach (DataRow dr in rolelist.Tables[0].Rows)
{
    listo.Add(new SelectListItem { Text = dr["user_role_name"].ToString(), Value = dr["user_role_Id"].ToString() }); 
}
ViewBag.urolelist = listo;

问题根因

  • ViewBag是单请求生效的动态属性,生命周期仅存在于当前单次请求,不会在GET、POST两次独立请求之间留存值,POST请求的上下文是全新的,无法读取GET阶段设置的ViewBag值。
  • 报错的POST Action中,下拉列表赋值逻辑没有覆盖所有返回视图的分支。最常见的场景是方法内加了模型校验逻辑,当ModelState.IsValid为false时直接执行return View(),该分支没有执行构造角色列表、给ViewBag.urolelist赋值的代码,最终视图读取到的ViewBag.urolelist为null。
  • 视图层构造SelectList时,将null作为第一个items参数传入,直接触发构造函数的空参数异常。注意即使是空的List<SelectListItem>(不含任何元素)传入,也不会触发这个错误,只有传入null值才会报这个错。
  • GET场景下代码能正常运行,是因为GET Action返回视图前必然执行列表赋值逻辑,不存在分支漏赋值的问题,传入SelectList的参数始终是有效对象,不会为null。

修复方案

  • 将构造角色下拉列表的逻辑抽成独立的私有方法,不管是GET请求、还是POST请求中任意分支返回视图前,都调用该方法给ViewBag.urolelist赋值,确保值不为null。
  • 控制器中已经构造了List<SelectListItem>类型的对象,不需要在视图层二次new SelectList包装,直接将ViewBag值传给asp-items即可,简化代码同时减少出错概率,调整后的视图代码如下:
    <select asp-for="Rolename" class="form-control" asp-items="ViewBag.urolelist"></select>
    
  • 给仓储层查询方法增加空值判断,避免存储过程执行异常返回空DataSet时,直接访问Tables[0]触发新的空引用异常,比如遍历前先判断ds.Tables.Count > 0。

内容的提问来源于stack exchange,提问作者Obasegun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:03:26