公共类EditVM{公共 int FooID { 获取;放;}公共列表酒吧{得到;放;}}公共类 BarVM{公共字符串名称 { 获取;放;}公共列表版本 { 得到;放;}}公共类 BarVersionVM{公共 int ID { 获取;放;}公共字符串名称 { 获取;放;}//不清楚你在哪里使用这个属性公共字符串版本 { 获取;放;}public bool IsSupported { 获取;放;}}
然后你的观点是
@model EditVM....@Html.HiddenFor(m => m.FooID)@for(int i = 0; i < Model.Bars.Count; i++){<字段集><legend>@Model.Bars[i].Name</legend>@Html.HiddenFor(m => m.Bars[i].Name)//如果你需要在 POST 方法中返回视图@for(int j = 0; j 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)
}</fieldset>}<input type="submit" value="保存"/>
How do you properly bind a Dictionary and it's values per key to checkboxes?
I can display them in the HTTPGET but binding the selected values again to HTTPPOST doesn't seem to work.
viewmodel
public class EditViewModel
{
public Foo Foo { get; set; }
public Dictionary<Bar, List<BarVersionEditVM>> 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; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(EditViewModel vm) {
// vm is there but Matrix are null.
// and only the ID of Foo property is filled in.
}
any suggestions?
解决方案
Unless your Dictionary has simple value types for both the Key and Value (e.g. public Dictionary<string, string>), the DefaultModelBinder requires that the form control name attributes be in the format
There are no HtmlHelper methods that will generate the correct html to allow binding to your Dictionary.
It is far simpler to create simple view model(s) to with IList<T> properties for the collections. Based on the view you have shown, those models would be
public class EditVM
{
public int FooID { get; set; }
public List<BarVM> Bars { get; set; }
}
public class BarVM
{
public string Name { get; set; }
public List<BarVersionVM> 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; }
}
and your view would then be
@model EditVM
....
@Html.HiddenFor(m => m.FooID)
@for(int i = 0; i < Model.Bars.Count; i++)
{
<fieldset>
<legend>@Model.Bars[i].Name</legend>
@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++)
{
<div>
@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)
</div>
}
</fieldset>
}
<input type="submit" value="Save" />