Bind multiple values to a single checkbox and post

2019-09-12 04:54发布

Model.cs

A campaign can have multiple images, that's why IEnumerable<int> ImageIdList.

public class Campaign
{
  public int Id { get; set; }
  public int CreatedBy { get; set; }
  public int UpdatedBy { get; set; }
  public IEnumerable<int> ImageIdList { get; set; }
}

View.cshtml

I want to download all the images related to a campaign, based on the ImageIdList, that's why I need to post all these ImageIds when a particular Campaign is checked and download button is clicked.

@model Campaign

    @{
      Layout = "....";
      var assets = Model.AssetsInCampaign.ToList();
    }
    @using (Html.BeginForm("action-method", "controller", FormMethod.Post))
    {
      <div class="btnSubmit">
        <input type="submit" value="Download Asset(s)" />
      </div>
      @foreach(var i in assets)
      {
        <div class="s_checkcol">
          <input type="checkbox" name="ids" />
          @foreach (var imageId in i.Where(c => c.AssetId == doc.FileDataId).SelectMany(c => c.ImageIdList))
          {
              <input type="hidden" name="ids" value=@(imageId)>
          }
        </div>
      }
    }

Controller.cs

public ActionResult DownloadFiles(IEnumerable<int> ids)
{
    // code
}

NOTE: Only a part of code(where I'm facing the problem) is provided here. Its a DB first approach and in no way I can alter that (ORDERS).

I tried the above, but all of the ids are posted to the controller no matter how many checkboxes are selected.

Question: How should I bind the IEnumerable<int> ImageIdList property to a checkbox in View.cs and post the data to Controller.cs so that only the ids of selected checkboxes are posted?

1条回答
别忘想泡老子
2楼-- · 2019-09-12 05:37

This is a nice practice... it will work and Iam working with such a manner (Iam sure that it will work very well) but one thing you have to be very carefull while coding this, little bit complicated

Iam taking this effort not only for as an answer to this particular question.

Its for all stackoverflow users. Because i never found the below method anyware in stackoverflow.

I get this method by a long search. You people can use this.

It will help you to avoid for loops to bind the Checkboxlist

Its the best good for re-usability (need a single line (max: 20-25 chars to bind a CheckBoxList in Razor))

CheckBoxListItem.cs

create a New Class CheckBoxListItem //you can use any other names

public class CheckBoxListItem
{
    public int ID { get; set; }
    public string Display { get; set; }
    public bool IsChecked { get; set; }
}

MyModel.cs

This is modelclass

public class MyModel
{
    [Key]        
    public int Id { get; set; }
    public string Name { get; set; }
    public IEnumerable<CheckBoxListItem> ChkList { get; set; }
}

HomeController.cs

This is controller

public ActionResult Index()
{
     var model = new MyModel(){
         Id = 0,
         Name = "Your Name",
         ChkList = dbContext.myTable.Select(x => new CheckBoxListItem { ID = x.MyTableFieldID, Display = x.MyTableFieldName, IsChecked = true })
         //If you need only int part, then just avoid to bind data on Display field
     };
     return View(model);
}

[HttpPost]
public ActionResult Index(MyModel myModel) //Your model object on PostAction
{
    IEnumerable<CheckBoxListItem> ChkList = myModel.ChkList; 
    // Here is your answer, You can see all your check box items (both checked and unchecked) in ChkList, it will shows all your checked items are true and non-checked items are false in IsChecked field 
}

Here you have to give more patiance

Goto the Folder View>Shared>EditorTemplates and RightClick Add>View... and Create a new View with the same name CheckBoxListItem.cshtml

CheckBoxListItem.cshtml

@model Project.Models.CheckBoxListItem
<div class="">
    @Html.HiddenFor(x => x.ID)
    <div class="">
        @Html.CheckBoxFor(x => x.IsChecked)
    </div>
    @Html.LabelFor(x => x.IsChecked, Model.Display, new { @class = "" })
</div>

Create your View

Index.cshtml

@model @model Project.Models.MyModel

<div class="form-group">
    @Html.LabelFor(model => model.Id, htmlAttributes: new { @class = "" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.Id, new { htmlAttributes = new { @class = "" } })
        @Html.ValidationMessageFor(model => model.Id, "", new { @class = "" })
    </div>
</div>

@Html.EditorFor(model => model.ChkList) //This only one line of code is enough to bind a checkBoxList in future

<input type="submit" value="Create" class="" />

You will get all these in your post action

查看更多
登录 后发表回答