0

I am learning mvc and try to populate checkbox list and get all selected values of checkbox list on submit button but i get null on button submit in the controller after post.The code for view and controller are as follows. The httpget part is working properly and shows all the checkbox as required. but after submitting problem occurs

View :

@model IEnumerable<MVCExtra.Models.paymentmethod>

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
@using(Html.BeginForm("Index", "Input", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{ 
    foreach (var item in Model)
    {
        @Html.HiddenFor(x => item.Id);
        @Html.HiddenFor(x => item.Name);
        @Html.CheckBoxFor(x=>item.isselected);
       
        @Html.DisplayFor(x => item.Name);
    }
    <input type="submit" value="submit"/>
}
</body>
</html>

Controller:

 public ActionResult Index()
        {
            List<paymentmethod> listpay = new List<paymentmethod>()
            {
                new paymentmethod() { Id="CS",isselected = true,Name = "Cash"},
                new paymentmethod() { Id="CH",isselected = false,Name = "Cheque"},
                new paymentmethod() { Id="CR",isselected = false,Name = "Credit"},
                new paymentmethod() { Id="BN",isselected = false,Name = "Bank"}

            };
            
            
            return View(listpay);
        }

        [HttpPost]
        public string Index(IEnumerable<paymentmethod> model)
        {
            if (model.Count(x => x.isselected) == 0)
            {
                return "no any option is selected";
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("You selected:");
                foreach (paymentmethod pay in model)
                {
                    if (pay.isselected == true)
                    {
                        sb.Append(":" + pay.Name);
                    }
                }

                return sb.ToString();
            }
        }
James Z
  • 12,209
  • 10
  • 24
  • 44
vikky
  • 31
  • 1
  • 7

2 Answers2

1

You need to use an indexer not a foreach loop for the model to post back correctly

for(int i=0; i < Model.Count(); i++)
{
    @Html.HiddenFor(x => Model[i].Id);
    @Html.HiddenFor(x => Model[i].Name);
    @Html.CheckBoxFor(x=>Model[i].isselected);

    @Html.DisplayFor(x => Model[i].Name);
}

EDIT: Forgot to mention, you'll need to convert your Model to a List rather than an IEnumerable

sheavens
  • 685
  • 7
  • 14
  • Does this work if rendering a partial view within the loop instead of having the actual form inputs? – d0rf47 Mar 10 '21 at 21:06
  • @d0rf47 Unfortunately it won't you need the index for the names to be built correctly they look something like Model_n__Name if they are part of a parent model, or [n].Name if the model is an enumeration where n is the index – sheavens Mar 15 '21 at 14:03
  • ah thats exactly what i figured I was just hoping there was a way :P i ended up using the indexing method as suggested above. Thanks again! – d0rf47 Mar 15 '21 at 16:04
0

You can use your foreach loop, but it needs to be placed outside of the beginform section, otherwise each time it loops through, it will replace the last set of data with the new set.

Also have a read of this (correct way of using CheckBoxFor) :) - Proper usage of .net MVC Html.CheckBoxFor

CRoberts
  • 286
  • 1
  • 6
  • 17