使用viewmodel中的列表将字典绑定到复选框

你如何正确地绑定一个字典和它的每个键的值复选框? 我可以在HTTPGET中显示它们,但是再次将所选值绑定到HTTPPOST似乎不起作用。

视图模型

public class EditViewModel { public Foo Foo { get; set; } public Dictionary<Bar, List> Matrix { get; set; } } public class BarVersionEditVM { public int ID { get; set; } public string Name { get; set; } public string Version { get; set; } public bool IsSupported { get; set; } } 

视图:

 
@foreach (var kvp in Model.Matrix.OrderByDescending(x => x.Key.Name)) {
@kvp.Key.Name @foreach (var version in kvp.Value) {
}
}

在View中我也尝试用foreach重写并使用Html助手,但没有成功:

@ Html.CheckBoxFor(model => model.Matrix [kvpair.Key] [i] .IsSupported)

控制器:

 [HttpPost] [ValidateAntiForgeryToken] public async Task Edit(EditViewModel vm) { // vm is there but Matrix are null. // and only the ID of Foo property is filled in. } 

有什么建议?

除非您的Dictionary具有KeyValue简单值类型(例如public Dictionary ),否则DefaultModelBinder要求表单控件name属性采用格式

    

没有HtmlHelper方法会生成正确的html以允许绑定到Dictionary

使用集合的IList属性创建简单视图模型要简单得多。 根据您展示的视图,这些模型将是

 public class EditVM { public int FooID { get; set; } public List Bars { get; set; } } public class BarVM { public string Name { get; set; } public List Versions { get; set; } } public class BarVersionVM { public int ID { get; set; } public string Name { get; set; } // not clear where you use this property public string Version { get; set; } public bool IsSupported { get; set; } } 

然后你的观点就会如此

 @model EditVM .... @Html.HiddenFor(m => m.FooID) @for(int i = 0; i < Model.Bars.Count; i++) { 
@Model.Bars[i].Name @Html.HiddenFor(m => m.Bars[i].Name) // in case you need to return the view in the POST method @for(int j = 0; j < Model.Bars[i].Versions.Count; j++) {
@Html.HiddenFor(m => m.Bars[i].Versions[j].ID) @Html.CheckBoxFor(m => m.Bars[i].Versions[j].IsSupported) @Html.LabelFor((m => m.Bars[i].Versions[j].IsSupported, Model.Bars[i].Versions[j].Version)
}
}