我正在开发一个ASP.Net MVC 3 Web应用程序,我在从复选框列表中获取值时遇到了一些困难。我已经阅读了有关Stackoverflow的大部分问题,但是,我仍然遇到了一些问题。
我有一个ViewModel
public class ViewModelCheckBox
{
public string Id { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
}
另一个使用上面的viewmodel的ViewModel
public class ViewModelAssignSubSpeciality
{
public ListItem Item { get; set; }
public IList<ViewModelCheckBox> SpecialityList { get; set; }
}
然后在我的控制器中
public ActionResult AssignSubSpeciality(int id)
{
//Get a list of all sub-specialities
var SpecialityList = _listService.GetListItemsByID(3).ToList();
//Get a list of sub-specialities for the the passed in id, this is either the id of a speciality or grade
IList<RelationshipSpecialitySub> assignedSpecialities = _listService.GetAssignedSubSpecialities(id).ToList();
var checkBoxList = new List<ViewModelCheckBox>();
foreach (ListItem item in SpecialityList)
{
ViewModelCheckBox chkBox = new ViewModelCheckBox { Id = item.listItemID.ToString(), Name = item.description };
//If sub-speciality exists in assignedSpecialities list, then make checkbox checked
foreach (var specilaity in assignedSpecialities)
{
if (specilaity.subID == item.listItemID)
{
chkBox.Checked = true;
}
else
{
chkBox.Checked = false;
}
}
checkBoxList.Add(chkBox);
}
ViewModelAssignSubSpeciality viewModel = new ViewModelAssignSubSpeciality();
viewModel.ListItem = _listService.GetListItemByID(id);
viewModel.SpecialityList = checkBoxList;
return View(viewModel);
}
上面控制器中的代码是获取所有可能的复选框列表项的列表,然后获取所有先前选中的复选框列表项的列表,并将其设置为true。
My View看起来像这样,循环遍历SpecialityList并为每个项目创建一个复选框,并在需要时将其选定值设置为true。
<fieldset>
<legend>Specialities</legend>
@foreach (var item in Model.SpecialityList)
{
<input type="checkbox" id="@item.Id" name="@item.Name" value="@item.Id" @(item.Checked ? "checked" : "") />
<label for="@item.Id">@item.Name</label><br />
}
<input type="submit" value="Save Changes" class="sepH_b" />
我的控制器中的HttpPost方法看起来像这样
public ActionResult AssignSubSpeciality(ViewModelAssignSubSpeciality model)
{
//delete all sub-specialities in tbl relationshipSpecialitySub for List
foreach (ViewModelCheckBox item in model.SpecialityList)
{
//_listService.DeleteSubSpecialityFromSpeciality(item.Id);
}
return RedirectToAction("ListItems", new { id = model.ListItem.listID });
}
然而,当我尝试在
中获取所选复选框时model.SpecialityList
我们总是空的。我不确定为什么它不包含ViewModelCheckBox列表。
有人可以帮我解决这个问题吗?
谢谢。
答案 0 :(得分:15)
我在我的视图模型中有一个可枚举的
public class CheckBoxItem
{
public string Code { get; set; }
public bool IsChecked { get; set; }
public string Label {get;set;}
}
然后我使用编辑器模板在页面上显示它们。
<p class="checkbox" style="display:inline">
<span style="margin-left:5px;">
@Html.HiddenFor(x => x.Code)
@Html.CheckBoxFor(x => x.IsChecked)
</span>
@Html.LabelFor(x => x.IsChecked, Model.Label)
</p>
在视图中,我使用以下内容在页面上显示它们。
@Html.EditorFor(m => m.MyEnumerableOfCheckBoxItem)
当回发表单时,模型被正确绑定。
希望这有帮助。
答案 1 :(得分:0)
这是因为您给了复选框名称@item.Name
。模型绑定器将检查它是否可以将其映射到模型中的特定属性,但它找不到它,因为它正在查找@item.Name
的值而不是SpecialtyList
属性。 / p>
Phil Haack有一篇关于模型绑定到列表的好文章。我建议你检查一下。
另外,我认为你不能将绑定模型绑定到自定义对象,因为进入的复选框的值只是字符串。您应该在模型上创建另一个属性为IEnumerable的属性,其中复选框的值是模型绑定的。它看起来像这样:
public IList<ViewModelCheckBox> SpecialityList { get; set; }
public IEnumerable<string> SpecialityListValues { get; set; }
这样,您可以使用SpecialityList
填充视图中的值,使用SpecialityListValues
来检索值。请注意,复选框的名称必须与SpecialityListValues
对应。
答案 2 :(得分:0)
@RubbleFord提供了一个很好的答案。但是,如果您在同一页面上创建了多个列表,则该列表可能会掉落,因为labels属性将引用页面上方的标签。
要解决此问题,我已将编辑器模板更改为:
<p class="checkbox" style="display:inline">
<label>
@Html.HiddenFor(x => x.Code)
@Html.CheckBoxFor(x => x.IsChecked)
@Model.Label
</label>
</p>
其他所有内容都相同,但是此复选框将标签包裹起来,因此可以删除For。