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

时间:2016-12-21 08:56:26

标签: c# asp.net asp.net-core asp.net-core-mvc

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

视图模型

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助手,但没有成功:

@ Html.CheckBoxFor(model =&gt; 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.
}

有什么建议吗?

1 个答案:

答案 0 :(得分:4)

除非Dictionary具有KeyValue的简单值类型(例如公开Dictionary<string, string>),否则DefaultModelBinder要求表单控件{ {1}}属性的格式为

name

没有<input .... name="Matrix[0].Key" value="..." /> <input .... name="Matrix[0].Value[0].ID" value="..." /> <input .... name="Matrix[0].Value[0].Name" value="..." /> 种方法会生成正确的html,以允许绑定到HtmlHelper

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

IList<T>

然后你的观点就是

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