Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
126 views
in Technique[技术] by (71.8m points)

c# - Multiple checkboxes in razor (using foreach)

I have a problem and I can't find solution. I'm using Razor and it is my VieModel class.

public class GroupToExport
{
    public GroupToExport()
    {
        ToExport = false;
    }

    [DisplayName("Export")]
    public bool ToExport { get; set; }
    public Group Group { get; set; }

}

public class GroupsToExport
{
    public GroupsToExport()
    {
        //refill list
    }

    public List<GroupToExport> ExportingGroups { get; set; }
}

View:

@using (Html.BeginForm("Export", "ElmahGroup", FormMethod.Post, new { id = "toExportForm" }))
{
//some divs
    <input type="submit" id="js-export-submit" value="Export" />
 @foreach (var item in Model.ExportingGroups)
                {
                    <tr>
                        <td class="js-export-checkbox">
                            @Html.CheckBoxFor(modelItem => item.ToExport)
                        </td>
                    </tr>
                }
//some divs
}

Controller:

public ActionResult Export(GroupsToExport model)
    {
        var groupsToExport = model.ExportingGroups.Where(x => x.ToExport).Select(x => x);
        throw new System.NotImplementedException();
    }

After submit "ToExport", in Controller, every group always has value 'false'. Even if all groups are checked.

Can somebody help me? What I'm doing wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You cannot use a foreach loop to generate controls for a collection. The html you're generating for each checkbox (and for the associated hidden input) is <input type="checkbox" name="item.ToExport" .../>. Your model does not contain a property which is named item.

Use a for loop

@for(int i = 0; i < Model.ExportingGroups.Count; i++)
{
  <tr>
    <td class="js-export-checkbox">
      @Html.CheckBoxFor(m => m.ExportingGroups[i].ToExport)
    </td>
  </tr>
}

Now your HTML will be

<input name="ExportingGroups[0].ToExport" .../>
<input name="ExportingGroups[1].ToExport" .../>

etc. which will correctly bind to your model

Edit

Alternatively you can use a custom EditorTemplate for typeof GroupToExport. Create a partial view /Views/Shared/EditorTemplates/GroupToExport.cshtml

@model yourAssembly.GroupToExport
<tr>
  <td class="js-export-checkbox">
    @Html.CheckBoxFor(m => m.ToExport)
  </td>
</tr>

And then in the main view

@Html.EditorFor(m => m.ExportingGroups)

The EditorFor() method will generate the correct html for each item in your collection based on the template.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...