我创建了以下控制器和视图模型。它允许从同一个选择列表中选择两个用户。
@model Mvc5App.Controllers.FormViewModel
@using (Html.BeginForm("Index", "Form", FormMethod.Post))
{
<br>
@Html.LabelFor(m => m.UserSelection1)
<br>
@Html.DropDownListFor(m => m.UserSelection1, Model.OptionsSelectList)
<br>
@Html.LabelFor(m => m.UserSelection2)
<br>
@Html.DropDownListFor(m => m.UserSelection2, Model.OptionsSelectList)
<br>
}
在剃须刀视图中,您可以看到我正在为DropDownFor帮助器使用相同的列表。
uint8_t
问题在于,如果UserSelection1已经有值,则UserSelection2将设置为该值,如果它为null。
选择第一个选择列表项不应该是空值吗?
我是否必须专门将其设置为空字符串以避免这种情况?
答案 0 :(得分:4)
DropDownListFor()
方法在内部构建一个新的IEnumerable<SelectListItem>
,以便根据绑定的属性值设置Selected
属性的值,但仅限于您绑定的属性不是null
。
如果是第一个DropDownListFor()
(UserSelection1
),则第3个项目为Selected = true"
。它还在ViewDataDictionary
。
如果是第二个DropDownListFor()
(对于UserSelection2
),则该属性的值为null
,因此该方法使用的不是构建新的IEnumerable<SelectListItem>
,而是使用ViewData
来自viewModel.UserSelection2 = "";
的缓存集合,已将第3项设置为已选中。
要了解这一切是如何运作的,您可以查看source code here。
您可以通过设置DropDownListFor()
的值来正常工作。另请注意,如果您要交换UserSelection2
方法的顺序,您会看到您期望的值(即“ - 选择 - ”将选择UserSelection1
而“绿色”选择{{1 }})
更好的选择(显示正确的结果)将是使用
FormViewModel viewModel= new FormViewModel()
{
UserSelection1 = "Green",
OptionsSelectList = new SelectList(new string[]{ "Red", "Green", "Blue" }),
}
return View(viewModel);
并将属性更改为public IEnumerable<SelectListItem> OptionsSelectList { get; set; }
,并在视图中使用
@Html.DropDownListFor(m => m.UserSelection1, Model.OptionsSelectList, "- Select -")
@Html.DropDownListFor(m => m.UserSelection2, Model.OptionsSelectList, "- Select- ")
答案 1 :(得分:1)
这种行为是有道理的。想一想......你从同一个OptionSelectList构建你的下拉列表。加载表单视图时,您的下拉列表最初都是使用选定的绿色值构建的。 UserSelection2中的空值表示下拉列表中没有值与之匹配,因此它将保持与第一个值相同的值。
要解决此问题,正如您猜测的那样,您需要将UserSelection2值设置为空字符串,该字符串现在与“请选择”项目匹配,以便选择其中一个。
所以,在Form控制器的Index方法中,只需执行以下操作:
viewModel.UserSelection2 = "";
答案 2 :(得分:0)
对于以后遇到这篇文章的任何人,我发现仅在传递给帮助程序的选择列表上调用ToArray()方法似乎可以解决所有情况。是否为空字符串
@Html.DropDownListFor(m => m.PurchaseTypeId, PurchaseTypeSelectList.ToArray(), new { @class = "form-control" })
当通过ajax请求/ Json响应动态添加表单字段并返回剃刀模板的表单部分时,这就是我最终用来处理int的原因吗?以及下拉列表中的字符串类型值。否则,当将下拉列表添加到dom中(页面加载后)时,它们将选择碰巧选择的内容进行渲染。
为了页面加载,还必须将其添加到我的编辑器模板的顶部:
@{
Layout = null;
List<SelectListItem> PurchaseTypeSelectList = ViewBag.PurchaseTypeSelectList ?? new List<SelectListItem>();
PurchaseTypeSelectList.ForEach(m => m.Selected = false);
}