从List <T>创建MVC3 CheckBoxFor并在Post上获取列表(使用更新的值)

Mec*_*h0z 8 .net c# asp.net-mvc-3

我在ViewModel中有一个List,我解析为View

List<BoolSetting> 
Run Code Online (Sandbox Code Playgroud)

BoolSetting:

    public class BoolSetting
{
    public BoolSetting(string displayName, bool value)
    {
        DisplayName = displayName;
        Value = value;
    }
    public string DisplayName { get; set; }
    public bool Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,我想打印列表中所有项目的复选框,因此列表位于视图使用的ViewModel中

@foreach(var boolSettingList in Model.BoolSettingList)
        {
            <div>
                @Html.CheckBox(boolSettingList.DisplayName, boolSettingList.Value)
                @boolSettingList.DisplayName
            </div>
        }
Run Code Online (Sandbox Code Playgroud)

问题是当我发布这个时,我的模型没有在我的ViewModel中的List中保存更新的设置(bool值),因此该对象为空.

我可以

foreach (var VARIABLE in userSettingConfigViewModel.BoolSettingList)
        {
            VARIABLE.Value = (bool)Request.Form[VARIABLE.DisplayName];

        }
Run Code Online (Sandbox Code Playgroud)

但是这个视图模型将有许多列表,其中一些将具有相同的名称!这样会引起冲突

那么有没有办法预先打印我所有的bool然后让MVC弄清楚将数据放回到List对象之后?我不能让CheckBoxFor工作,因为它想要一个表达式,我无法找到一种方法来通过我的列表迭代

我可以通过为BoolSetting制作模板并使用List来修复模板吗?

Dar*_*rov 18

首先修复视图模型并删除自定义构造函数,否则默认模型绑定器将无法实例化它,您将不得不编写自定义模型绑定器和东西:

public class BoolSetting
{
    public string DisplayName { get; set; }
    public bool Value { get; set; }
}

public class MyViewModel
{
    public List<BoolSetting> Settings { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后编写一个控制器操作,用于填充视图模型:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Settings = new[] 
            {
                new BoolSetting { DisplayName = "name 1", Value = true },
                new BoolSetting { DisplayName = "name 2", Value = false },
                new BoolSetting { DisplayName = "name 3", Value = true },
            }.ToList()
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后是一个view(~/Views/Home/Index.cshtml),你只需使用编辑器模板,不写任何foreach循环或弱类型的html助手,如Html.CheckBox.通过使用编辑器模板,您将确保所有输入字段都具有正确的名称,以便默认模型绑定器能够在回发期间将其值提取到视图模型中:

@model MyViewModel
@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.Settings)
    <button type="submit">OK</button>
}
Run Code Online (Sandbox Code Playgroud)

最后是视图模型的相应编辑器模板,它将为collection(~/Views/Home/EditorTemplates/BoolSetting.cshtml)的每个元素呈现:

@model BoolSetting
<div>
    @Html.CheckBoxFor(x => x.Value)
    @Html.LabelFor(x => x.Value, Model.DisplayName)
    @Html.HiddenFor(x => x.DisplayName)
</div>
Run Code Online (Sandbox Code Playgroud)