我有以下代码行:
@Html.DropDownListFor(x => x.TimeOption, new SelectList(Model.TimeOptions, "Value", "Name", (int)Model.TimeOption))
下拉列表已正确构建,并且“选定”确实正确,但MVC不会在选择了正确项目的情况下绘制下拉列表。标记不会在选项上输出选定的属性。
输出呈现为:
<option value="0">Past Day</option>
<option value="1">Past Week</option>
<option value="2">Past Month</option>
<option value="3">Past Year</option>
<option value="4">Start of Time</option>
然而,如果您查看附加的屏幕截图,您可以看到它已正确选择:
这只影响GET,而不影响POST。想法?
答案 0 :(得分:22)
这往往会让人们陷入困境 - 显然MVC 5的路线图包含更直观的DropDownList助手。
当你这样做时:
@Html.DropDownListFor(x => x.TimeOption ...)
... HTML帮助程序将执行其功能而非的所有内容,以使用您在Selected = true
中设置为SelectList
的值。它会:
ModelState
获取 - 它不会获得GET请求ViewData
获取它 - 将获取它,因为您的模型上有TimeOption
属性。只有当这两次尝试失败时,它才会屈服,并使用您要求它使用的内容。
因此,在您的情况下,它将使用模型上TimeOption
的当前值作为选定值。这应该没问题,因为这是你在SelectList
中所要求的((int)Model.TimeOption
),对吗?
错误。因为不会将您的财产(enum
?)投射到int
,就像您一样。它会将其转换为字符串。对于产生枚举名称的enum
- 例如PastMonth
。如果TimeOption
是您的自定义类,那么它将是ToString()
的结果。
然后,当它没有找到该字符串作为您的<select>
值之一时(因为它们都是整数),它决定不进行任何选择。
简而言之:SelectListItem.Selected
对助手没有影响。如果您的帮助程序调用指定了一个名称(通过字面或通过lambda表达式),则帮助程序将使用ModelState
或ViewData
中具有该名称的任何内容,并将其转换为字符串。
在大多数情况下,这会发生在枚举中。解决它的最简单方法是使用枚举的名称而不是其int表示作为SelectListItem
的值。
答案 1 :(得分:2)
上面已经有一个很好的解释,为什么它不起作用,但只是添加我的2p
一般来说,我更喜欢使用可枚举的SelectListItems作为dropdownitems的来源,尽管两者都应该有用。这样做更可取,因为不需要指定选择哪个项目 - MVC帮助程序将从Value匹配TimeOption.ToString()方法的那个推断出它。
即
@Html.DropDownListFor(x => x.TimeOption, ((IEnumerable<TimeOption>)Model.TimeOptions).ToList().ConvertAll(y => new SelectListItem(){Text = y.Name, Value = y.Value.ToString()})
注意 - 我不确定Model.TimeOptions的类型是什么 - 如果它不是IEnumerable&lt; TimeOption&GT;然后更换它。 (如果它已经是一个列表,那么.ToList()就没有必要了)