将字典与视图模型中的列表绑定到复选框 [英] Bind Dictionary with list in viewmodel to checkboxes

查看:26
本文介绍了将字典与视图模型中的列表绑定到复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

视图模型

公共类 EditViewModel{公共 Foo Foo { 得到;放;}public Dictionary>矩阵 { 得到;放;}}公共类 BarVersionEditVM{公共 int ID { 获取;放;}公共字符串名称 { 获取;放;}公共字符串版本 { 获取;放;}public bool IsSupported { 获取;放;}}

查看:

<div class="row">@foreach(在 Model.Matrix.OrderByDescending(x => x.Key.Name) 中的 var kvp){<div class="col-md-2 col-lg-2"><字段集><legend>@kvp.Key.Name</legend>@foreach(kvp.Value 中的 var 版本){<div><input type="checkbox" id="@version.ID" value="@version.IsSupported" name="@version.Name" @(version.IsSupported ? "checked="checked"" : "")/><label>@version.Version:</label>

}</fieldset>

}

<input type="hidden" asp-for="@Model.Foo.ID"/><input type="submit" value="Save" class="btn btn-default"/></表单>

在视图中,我也尝试使用 foreach 和 Html helpers 进行重写,但没有成功:

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

控制器:

[HttpPost][验证AntiForgeryToken]公共异步任务编辑(编辑视图模型虚拟机){//vm 存在,但 Matrix 为空.//并且只填写 Foo 属性的 ID.}

有什么建议吗?

解决方案

除非您的 DictionaryKeyValue 都具有简单的值类型>(例如public Dictionary),DefaultModelBinder 要求表单控件name 属性的格式为

<input .... name="Matrix[0].Value[0].ID" value="..."/><input .... name="Matrix[0].Value[0].Name" value="..."/>

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

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

公共类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; }
}

view:

<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>

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)

controller:

[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

<input .... name="Matrix[0].Key" value="..." />
<input .... name="Matrix[0].Value[0].ID" value="..." />
<input .... name="Matrix[0].Value[0].Name" value="..." />

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" />

这篇关于将字典与视图模型中的列表绑定到复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
C#/.NET最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆