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