【问题标题】:ASP.NET MVC - Model binding a set of dynamically generated checkboxes - how toASP.NET MVC - 模型绑定一组动态生成的复选框 - 如何
【发布时间】:2009-06-23 08:53:59
【问题描述】:

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

我的 ViewModel 类 (DocumentAddEditModel) 包含一个字典 (Dictionary),其中每个条目的字符串是每个复选框的名称/标签,布尔值表示复选框是否被选中:

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

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

在我的控制器中,处理表单的 GET 请求的操作按如下方式填充字典:

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

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

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

documentAddEdit.Model.CategoryCheckboxes 始终为空。我该如何设置,以便 CategoryCheckboxes 字典正确填充复选框的名称和选中/未选中的布尔值?

谢谢

【问题讨论】:

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


    【解决方案1】:

    如果您将复选框绑定到 Dictionary&lt;string, bool&gt;,请尝试以下操作:

    <% 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&lt;T1, T2&gt;,您的表单必须包含带有“CategoryCheckboxes[n].Key”和“CategoryCheckboxes[n].Value”ID/Names 的输入,其中 n 必须从零开始且不间断。

    【讨论】:

    • 感谢eu-ge-ne,这似乎可以解决问题,您能否澄清一下这里发生了什么?我知道,由于复选框控件(
    • 我再次意识到 Html.CheckBox() htmlhelper 生成了第二个隐藏字段,其名称属性等于可见复选框的名称属性,但是当我比较生成的 html 时未选中复选框时:
    • 检查时的内容:
    • 唯一的区别是在选中状态下,'checked' 属性设置为“checked”。保存实际数据的“值”属性不会改变。另外,如果不必再次求助于隐藏元素(即不使用 Html.Checkbox() 帮助器)就不可能实现我想要的吗?)谢谢
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      更简单的:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-24
        • 2011-07-20
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 2018-07-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多