ASP.NET MVC - 模型绑定一组动态生成的复选框 - 如何

时间:2009-06-23 08:53:59

标签: asp.net-mvc model-view-controller

我正在尝试建模绑定一组动态生成的复选框,以便在控制器操作中处理它们,但无法使模型绑定发生。这是场景:

我的ViewModel类(DocumentAddEditModel)包含一个字典(Dictionary< string,bool>),每个条目的字符串是每个复选框的名称/标签,以及指示是否选中该复选框的布尔值:

    public class DocumentAddEditModel
    {
        ...
        private Dictionary<string, bool> _categoryCheckboxes = new Dictionary<string,bool>();
        ...

        ...
        public Dictionary<string, bool> CategoryCheckboxes
        {
            get { return _categoryCheckboxes; }
            set { _categoryCheckboxes = value; }
        }
        ...
    }
}

在我的控制器中,处理表单的GET请求的操作会填充dictonary,如下所示:

public class DocumentsController : Controller
{
    [RequiresAuthentication]
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Add()
    {
        DocumentAddEditModel documentAddEditModel = new DocumentAddEditModel();
        ...
        Dictionary<string, bool> categoryCheckboxes = new Dictionary<string, bool>();
        ...
        string[] categories = Enum.GetNames(typeof(Category));

        foreach (string category in categories)
            categoryCheckboxes.Add(category, false);

        documentAddEditModel.CategoryCheckboxes = categoryCheckboxes;

        return View(documentAddEditModel);
    }
}

在视图中,我有以下内容来生成复选框:

<% foreach (KeyValuePair<string, bool> categoryCheckbox in ViewData.Model.CategoryCheckboxes)
    {%>
    <input class="checkbox" type="checkbox" name="CategoryCheckboxes[0].Key" id="<%= categoryCheckbox.Key %>" />
    <label class="categoryLabel" for="<%= categoryCheckbox.Key %>"><%= categoryCheckbox.Key %></label>
<% } %>

但我认为这是问题所在。不确定name属性中需要做什么。问题是,一旦回复到DocumentsController中的以下操作方法:

[RequiresAuthentication]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(DocumentAddEditModel documentAddEditModel)
{
    ...
}

documentAddEdit.Model.CategoryCheckboxes始终为null。我如何设置它以便为CheckCheckboxes字典正确填充名称和复选框的已检查/未选中bool值?

由于

3 个答案:

答案 0 :(得分:10)

如果您将复选框绑定到Dictionary<string, bool>,请尝试以下操作:

<% var i = 0; %>
<% foreach (KeyValuePair<string, bool> categoryCheckbox in Model.CategoryCheckboxes) {%>

    <input type="hidden" name="<%= String.Format("CategoryCheckboxes[{0}].Key", i) %>" value="<%= categoryCheckbox.Key %>" />
    <%= Html.CheckBox(String.Format("CategoryCheckboxes[{0}].Value", i), categoryCheckbox.Value) %>

    <label class="categoryLabel" for="<%= categoryCheckbox.Key %>"><%= categoryCheckbox.Key %></label>

    <% i++; %>
<% } %>

希望这有帮助

<强>更新:

对于绑定到IDictionary<T1, T2>,您的表单必须包含带有“CategoryCheckboxes [n] .Key”和“CategoryCheckboxes [n] .Value”Ids / Names的输入,其中n必须从零开始且不间断。

答案 1 :(得分:1)

隐藏元素是asp.net的运作方式。在webforms版本中,它是ViewState,它是一个巨大的隐藏字段,在MVC中,每个控件的重量更轻,更直接的隐藏字段。我不确定这有什么不对或令人不安。不知何故,你必须保持状态,你可以做客户端或服务器端。我建议客户端提供非敏感信息,如果服务器在回发等之间重新启动它仍将存在。

答案 2 :(得分:0)

更简单:

@foreach (var pair in Model.CategoryCheckboxes)
{
    @Html.CheckBoxFor(m=>m.CategoryCheckboxes[pair.Key])
}