当数据库值为NULL时,在下拉列表中添加空选项
本文关键字:下拉列表 添加 选项 数据库 NULL | 更新日期: 2023-09-27 18:05:13
我有一个数据库表,有几个外键字段。当我加载一个记录进行编辑时,有下拉列表,在Razor中使用@Html.DropDownList
创建,它正确地显示了外键列引用的表中的可能值。而且,因为我正在编辑一条记录,如果一个值之前已经从外键表中被选中,那么它的ID就在主表的外键列中,正如您所期望的那样。
但是,如果我加载编辑的记录在一个外键列中没有值-即,列中的值为NULL(并且它们都是可空的,原因超出了我的控制),默认情况下,下拉菜单选择了第一个选项。这不仅会产生误导,因为没有办法知道这个选项被显示是因为它以前被保存过,还是因为它只是第一个选项,这还意味着当我随后保存记录时,第一个选项的值被错误地保存到数据库中。
我需要的是每个下拉列表还包括一个"未知"选项,动态添加(即不在数据库中),这是选择当页面加载时,如果基础外键列有一个NULL值,这可以由用户选择,如果他们想改变以前保存的值为NULL。
当页面加载时,我使用jQuery给下拉列表添加一个值没有问题,像这样:
$("select").prepend("<option value=''>Unknown</option>")
但是,当页面加载时,即使这个新选项作为列表中的第一个选项成功添加,它也没有被选中。第一个"真正的"选择是。而且,即使我可以使用jQuery强制选择'dummy'选项,也会在数据库中存在真实值的下拉框中选择dummy选项。
这真的不像是什么不寻常或晦涩的事情,但我在谷歌上搜索了一个下午后,一直在努力寻找任何解决方案。我尝试了各种各样的东西,从堆栈溢出,我认为我可能能够使工作,但无济于事。
谁能提出解决方案?我认为在控制器中添加一个"虚拟"选项可能是最简洁的方法,如果我能找到方法的话。我很惊讶这不是一个很常见的问题!
加载下拉列表值的控制器代码如下:
ViewBag.PremisesID = new SelectList(db.Premises, "ID", "StreetName", colicCase.PremisesID);
下拉菜单对应的Razor如下所示:
<div class="form-group">
@Html.LabelFor(model => model.PremisesID, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.DropDownList("PremisesID", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.PremisesID, "", new { @class = "text-danger" })
</div>
</div>
该功能已经通过使用DropDownList()
或DropDownListFor()
方法的重载之一内置到MVC中,该方法接受optionLabel
参数,例如
public static MvcHtmlString DropDownList(
this HtmlHelper htmlHelper,
string name,
IEnumerable<SelectListItem> selectList,
string optionLabel,
object htmlAttributes
)
或强类型版本
public static MvcHtmlString DropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> selectList,
string optionLabel,
object htmlAttributes
)
,其中optionLabel
的值将被添加为null
值的第一个选项(生成例如<option value="">Unknown</option>
)。
我强烈建议您使用强类型版本,并且您使用带有SelectList
属性的视图模型,而不是使用ViewBag
,但在任何情况下,不要为您绑定到的属性和ViewBag
属性使用相同的名称(有关更多细节,请参阅此回答)
public class MyViewModel
{
....
public int? PremisesID { get; set; }
public IEnumerable<SelectListItem> PremisesList { get; set; }
....
}
和GET方法
var model = new MyViewModel()
{
.... // map properties from the data model
PremisesID = dataModel.PremisesID,
PremisesList = new SelectList(db.Premises, "ID", "StreetName")
};
return View(model);
和视图
@Html.DropDownListFor(m => m.PremisesID, Model.PremisesList, "Unknown", new { @class = "form-control" })
如果PremisesID
的值是null
或者与Premises
表中的ID
的值不匹配,则选择第一个选项