将具有视图模型中的列表的字典绑定到复选框 [英] Bind Dictionary with list in viewmodel to checkboxes
问题描述
您如何正确绑定字典并将其每个键的值绑定到复选框? 我可以在HTTPGET中显示它们,但是将所选的值再次绑定到HTTPPOST似乎无效.
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
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; }
}
视图:
<form asp-action="Edit">
<div class="row">
@foreach (var kvp in Model.Matrix.OrderByDescending(x => x.Key.Name))
{
<div class="col-md-2 col-lg-2">
<fieldset>
<legend>@kvp.Key.Name</legend>
@foreach (var version in kvp.Value)
{
<div>
<input type="checkbox" id="@version.ID" value="@version.IsSupported" name="@version.Name" @(version.IsSupported ? "checked=\"checked\"" : "") />
<label>@version.Version:</label>
</div>
}
</fieldset>
</div>
}
</div>
<input type="hidden" asp-for="@Model.Foo.ID" />
<input type="submit" value="Save" class="btn btn-default" />
</form>
在视图中,我还尝试使用foreach和Html帮助程序进行重写,但未成功:
In the View I tried also to rewrite with foreach and using Html helpers, but without success:
@ Html.CheckBoxFor(model => model.Matrix [kvpair.Key] [i] .IsSupported)
@Html.CheckBoxFor(model => model.Matrix[kvpair.Key][i].IsSupported)
控制器:
[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.
}
有什么建议吗?
推荐答案
除非您的Dictionary
具有Key
和Value
的简单值类型(例如,公共Dictionary<string, string>
),否则DefaultModelBinder
要求表单控件name
属性的格式为
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
<input .... name="Matrix[0].Key" value="..." />
<input .... name="Matrix[0].Value[0].ID" value="..." />
<input .... name="Matrix[0].Value[0].Name" value="..." />
没有HtmlHelper
方法会生成正确的html以允许绑定到您的Dictionary
.
There are no HtmlHelper
methods that will generate the correct html to allow binding to your Dictionary
.
使用集合的IList<T>
属性创建简单的视图模型要容易得多.根据您显示的视图,这些模型将是
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; }
}
然后您的视图将
@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" />
这篇关于将具有视图模型中的列表的字典绑定到复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!