[c#]将字典在 viewmodel 中列表绑定到对应的复选框

标签: Asp.net C#
发布时间: 2017/2/25 3:55:52
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

你如何正确绑定一本字典和它的每个复选框的关键值? 我可以显示它们在公共但再一次将所选的值绑定到 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 (模型 => 模型。矩阵 [kvpair。关键] [i]。兼作)

控制器︰

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

除非你 Dictionary 具有简单值类型为两个 KeyValue (例如公共 Dictionary<string, string> )、 DefaultModelBinder 要求窗体控制 name 格式的属性是

<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

它是简单得多,若要创建简单的视图模型到与 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; }
}

然后将你的观点

@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" />
赞助商