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

Razor视图动态创建SelectList遇空引用错误的技术问询

Razor视图中动态创建SelectList的正确技巧

问题场景

视图模型定义

public class ViewModel {
    public int SelectedItem {get; set;}
    public List<Meeting> Meetings {get; set;}
}
public class Meeting {
    public int Id {get; set;}
    public string Title {get; set;}
    public string Info {get; set;}
}

尝试用@Html.DropDownListFor创建size为10的列表框,使用以下方式快速生成SelectList:

@Html.DropDownListFor(model => model.SelectedItem,
    new SelectList(Model.Meetings, "Meeting.Id", "Meeting.Title"),
    new {@id="itemList"})

首次加载Meetings为空列表时正常,但填充数据后出现未将对象引用设置到对象实例错误。

后续尝试在控制器中创建SelectList存入ViewBag:

ViewBag.mySelectList = new SelectList(ViewModel.Meetings, "Meeting.Id", "Meeting.Title")

调试可见SelectList已包含数据,但视图仍报相同错误。

仅当手动生成SelectListItem列表再创建SelectList时功能正常:

var selList = Meetings.Select(m => new SelectListItem {
    Value = m.Id.ToString(),
    Text = m.Title}).ToList();
mySelectList = new SelectList(selList, "Value", "Text");

问题根源

创建SelectList时指定的dataValueField和dataTextField参数错误。当数据源是List<Meeting>这类实体集合时,这两个参数应该直接写实体的属性名"Id"和"Title",而非"Meeting.Id"和"Meeting.Title"——SelectList会自动遍历集合中的每个Meeting对象,直接访问其属性,不需要额外添加类名前缀。

当Meetings为空时,SelectList不会触发属性解析逻辑,因此不报错;一旦集合有数据,它尝试访问每个对象的Meeting.Id属性,而Meeting类型本身并没有名为Meeting的嵌套属性,最终抛出空引用错误。


正确的动态创建方式

方式1:视图中直接创建

适合简单场景,无需在控制器额外处理:

@Html.DropDownListFor(model => model.SelectedItem,
    // 处理Meetings为null的情况,避免潜在错误
    new SelectList(Model.Meetings ?? new List<Meeting>(), "Id", "Title"),
    new {@id="itemList", size="10"})

方式2:控制器中创建并存入ViewBag

适合需要在多个视图复用下拉列表的场景:

// 控制器代码
// 确保Meetings不为null
var meetings = viewModel.Meetings ?? new List<Meeting>();
ViewBag.mySelectList = new SelectList(meetings, "Id", "Title");

视图中调用:

@Html.DropDownListFor(model => model.SelectedItem,
    (SelectList)ViewBag.mySelectList,
    new {@id="itemList", size="10"})

方式3:预生成SelectListItem集合

适合需要对选项做额外处理(如添加默认项、过滤选项)的复杂场景:

// 控制器代码
var selList = (viewModel.Meetings ?? new List<Meeting>())
    .Select(m => new SelectListItem {
        Value = m.Id.ToString(),
        Text = m.Title
    })
    // 可选:添加默认提示选项
    .Prepend(new SelectListItem { Value = "", Text = "-- 选择会议 --" })
    .ToList();
// 视图模型中需添加对应的List<SelectListItem>属性
viewModel.MySelectList = selList;

视图中调用:

@Html.DropDownListFor(model => model.SelectedItem,
    Model.MySelectList,
    new {@id="itemList", size="10"})

总结

  • 当数据源为实体集合时,SelectList的dataValueField和dataTextField直接写实体的属性名,不要加类名前缀。
  • 始终处理集合为null的情况,避免空引用错误。
  • 根据场景选择合适的创建方式:简单场景用视图直接创建,跨视图复用用ViewBag,复杂逻辑用预生成SelectListItem。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 02:02:06