简体   繁体   中英

Checkbox list for complex type in asp.net mvc

I have below class :

public class ControllerSecurityModel
{
    public string ControlleName { get; set; }
    public string DisplayName { get; set; }
    public List<ActionSecurityModel> actions { get; set; }
}
public class ActionSecurityModel
{
    public string ActionName { get; set; }
    public string DisplayName { get; set; }
    public bool IsChecked { get; set; }
}

and a model :

public class PageRoleModel
{
    public List<ControllerSecurityModel> AllPages { get; set; }

    public List<ControllerSecurityModel> SelectedPage { get; set; }
}

I want to have checkbox for each "ActionSecurityModel" , I write below view :

<% using (Html.BeginForm())
   {%>
<% foreach (var cont in Model.AllPages)
   {%>
<fieldset>
    <legend>
        <%= cont.DisplayName  %></legend>
    <% foreach (var act in cont.actions)
       {%>
    <%: Html.CheckBoxFor(x => act.IsChecked) %>
    <%: Html.Label(act.DisplayName) %>
    <% } %>
</fieldset>
<% } %>
<input type="submit" value="save"/>
<% } %>

and this my controller action :

    public ActionResult SetRole()
    {
        PageRoleModel model = new PageRoleModel();

        return View(model);
    }

    [HttpPost]
    public ActionResult SetRole(PageRoleModel model)
    {
        return View(model);
    }

but when I submit form the model is null? How can I submit checkboxes and save them?

Like this:

<% using (Html.BeginForm()) { %>
    <% for (var i = 0; i < Model.AllPages.Count; i++) { %>
    <fieldset>
        <legend>
            <%= Model.AllPages[i].DisplayName %>
        </legend>
        <% for (var j = 0; j < Model.AllPages[i].actions.Count; j++ ) { %>
            <%= Html.CheckBoxFor(x => x.AllPages[i].actions[j].IsChecked) %>
            <%= Html.Label(Model.AllPages[i].actions[j].DisplayName) %>
        }
    </fieldset>
    <% } %>
    <input type="submit" value="save"/>
<% } %>

To understand why my solution works and your not, please read about the expected wire format that the default model binder uses for collections. Then look at the generated names of the form input fields by browsing the generated HTML source code - you will quickly see a fundamental difference in the name attribute of the checkbox.

Also don't expect to get your entire model bound in the POST action. You only have a single input field inside your form - a checkbox. So that's the only value that's gonna be sent to the server and bound to the model. If you needed the other values as well you could include them as hidden fields:

<!-- in the outer loop: -->
<% =Html.HiddenFor(x => x.AllPages[i].DisplayName) %>
...
<!-- and then in the inner loop -->
<%= Html.HiddenFor(x => x.AllPages[i].actions[j].ActionName) %>
<%= Html.HiddenFor(x => x.AllPages[i].actions[j].DisplayName) %>
... and so on ...

Also I would very strongly recommend you using editor templates instead of writing those loops in your views. They automatically will take care of generating proper names for your input fields so that you don't have to worry about. I have gazillions of answers on this topic. Just Google my name and add editor templates asp.net mvc to your search and you should get many results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM