在视图中显示之前检查 ListBoxFor selectedValues 是否为空?
Check if ListBoxFor selectedValues is null before display in view?
我在编辑模式下的窗体上有许多 ListBoxFor 元素。如果该字段中记录了数据,那么当表单打开时,先前选择的项目将正确显示。如果该字段为空,但会抛出错误,因为 items 参数不能为 null。有没有办法在视图中检查是否有数据使用带有四个参数的 ListBoxFor 但如果没有只使用三个参数,则忽略所选项目?
这就是我声明 ListBoxFor 的方式:
@Html.ListBoxFor(model => model.IfQualityPoor, new MultiSelectList(ViewBag.IfPoor, "Value", "Text", ViewBag.IfQualityPoorSelected), new { @class = "chosen", multiple = "multiple" })
我正在使用 ViewBag 传递 ICollection,它保存选定的项目作为控制器,然后加入或拆分字符串以绑定到模型字段。 MultiSelectLists 对我来说总是有问题。
您的问题并不完全清楚,但您自己的问题比需要使用 ListBoxFor
更难。 DropDownListFor
或 ListBoxFor
所需要的只是一个 IEnumerable<SelectListItem>
。 Razor 将负责根据 ModelState
.
选择任何适当的值
因此,假设 ViewBag.IfPoor
是 IEnumerable<SelectListItem>
,您认为需要的是:
@Html.ListBoxFor(m => m.IfQualityPoor, (IEnumerable<SelectListItem>)ViewBag.IfPoor, new { @class = "chosen" })
正确的选项将根据您模型上 IfQualityPoor
的值标记为 selected
,因为它们应该如此。此外,没有必要在 htmlAttributes
参数中传递 multiple = "multiple"
,因为您只需使用 ListBoxFor
而不是 DropDownListFor
。
如果您使用视图模型,然后将您的选项添加为 属性,那就更好了。然后,您不必担心在视图中进行强制转换,这始终是引入运行时异常的好方法。例如:
public class FooViewModel
{
...
public IEnumerable<SelectListItem> IfQualityPoorOptions { get; set; }
}
然后,在返回视图之前在操作中设置它(而不是设置 ViewBag
)。最后,在您看来:
@Html.ListBoxFor(m => m.IfQualityPoor, Model.IfQualityPoorOptions, new { @class = "chosen" })
更简单,而且您永远不会遇到任何问题。
更新(基于评论)
处理将列表扁平化为数据库存储字符串的最佳方法是为此使用特殊的 属性,然后自定义 getter 和 setter 映射 to/from。例如:
public string IfQualityPoor
{
get { return IfQualityPoorList != null ? String.Join(",", IfQualityPoorList) : null; }
set { IfQualityPoorList = !String.IsNullOrWhiteSpace(value) ? value.Split(',').ToList() : null; }
}
[NotMapped]
public List<string> IfQualityPoorList { get; set; }
然后,你 post to/interact 和 IfQualityPoorList
,当你保存时,正确的字符串将自动设置在数据库中。
我在编辑模式下的窗体上有许多 ListBoxFor 元素。如果该字段中记录了数据,那么当表单打开时,先前选择的项目将正确显示。如果该字段为空,但会抛出错误,因为 items 参数不能为 null。有没有办法在视图中检查是否有数据使用带有四个参数的 ListBoxFor 但如果没有只使用三个参数,则忽略所选项目?
这就是我声明 ListBoxFor 的方式:
@Html.ListBoxFor(model => model.IfQualityPoor, new MultiSelectList(ViewBag.IfPoor, "Value", "Text", ViewBag.IfQualityPoorSelected), new { @class = "chosen", multiple = "multiple" })
我正在使用 ViewBag 传递 ICollection,它保存选定的项目作为控制器,然后加入或拆分字符串以绑定到模型字段。 MultiSelectLists 对我来说总是有问题。
您的问题并不完全清楚,但您自己的问题比需要使用 ListBoxFor
更难。 DropDownListFor
或 ListBoxFor
所需要的只是一个 IEnumerable<SelectListItem>
。 Razor 将负责根据 ModelState
.
因此,假设 ViewBag.IfPoor
是 IEnumerable<SelectListItem>
,您认为需要的是:
@Html.ListBoxFor(m => m.IfQualityPoor, (IEnumerable<SelectListItem>)ViewBag.IfPoor, new { @class = "chosen" })
正确的选项将根据您模型上 IfQualityPoor
的值标记为 selected
,因为它们应该如此。此外,没有必要在 htmlAttributes
参数中传递 multiple = "multiple"
,因为您只需使用 ListBoxFor
而不是 DropDownListFor
。
如果您使用视图模型,然后将您的选项添加为 属性,那就更好了。然后,您不必担心在视图中进行强制转换,这始终是引入运行时异常的好方法。例如:
public class FooViewModel
{
...
public IEnumerable<SelectListItem> IfQualityPoorOptions { get; set; }
}
然后,在返回视图之前在操作中设置它(而不是设置 ViewBag
)。最后,在您看来:
@Html.ListBoxFor(m => m.IfQualityPoor, Model.IfQualityPoorOptions, new { @class = "chosen" })
更简单,而且您永远不会遇到任何问题。
更新(基于评论)
处理将列表扁平化为数据库存储字符串的最佳方法是为此使用特殊的 属性,然后自定义 getter 和 setter 映射 to/from。例如:
public string IfQualityPoor
{
get { return IfQualityPoorList != null ? String.Join(",", IfQualityPoorList) : null; }
set { IfQualityPoorList = !String.IsNullOrWhiteSpace(value) ? value.Split(',').ToList() : null; }
}
[NotMapped]
public List<string> IfQualityPoorList { get; set; }
然后,你 post to/interact 和 IfQualityPoorList
,当你保存时,正确的字符串将自动设置在数据库中。