1

I am using html.checkbox in my mvc appplication , it will generate the html like

<input checked="checked" id="cb17" name="reports" type="checkbox" value="sdf" />
<input name="reports" type="hidden" value="false" /> 

    <input checked="checked" id="cb18" name="reports" type="checkbox" value="ty" />
<input name="reports" type="hidden" value="false" />

when the form gets posted it is sending all the values of html.checkbox to mvc action through model binding concept.

reports[0]-"sdf"
reports[1]-"false"
reports[2]="ty"
reports[3]="false" 

model:

 public IEnumerable<string> reports{ get; set; }

i knew html.checkbox will create the hidden fields internally, but when i posting the form it need to send either one value of checkbox. why it is sending hidden fields too. how to avoid this.

referred the below link

asp.net mvc: why is Html.CheckBox generating an additional hidden input

but not able to get the proper understanding.

Community
  • 1
  • 1
SivaRajini
  • 7,225
  • 21
  • 81
  • 128
  • The `CheckBox()` method is for binding to a `booean` property, not a `string` (it correctly generates a `` and `` which will correctly bind to a `boolean` property when the form is submitted. Do not use `CheckBox()` for binding to a `string`. You have not shown your model, or what your attempting to bind to, or the method your posting back to so its impossible to understand why you trying to use this hack. –  Dec 20 '15 at 00:24
  • @stephen updated the model – SivaRajini Dec 21 '15 at 05:14
  • You model is `IEnumerable` (not `bool`) so just manually generate the html using `` id you want to receive an array of the values which have been checked. –  Dec 21 '15 at 05:17
  • But ideally you should be creating a view model and binding to it. The model would contain (say) `string Name` and `bool IsSelected` and use a `for` loop to generate the controls - refer [this answer](http://stackoverflow.com/questions/29542107/pass-list-of-checkboxes-into-view-and-pull-out-ienumerable/29554416#29554416) for an example –  Dec 21 '15 at 05:19
  • @SivaRajini Can you tell us what you are trying to do? As far as I can see, you have a list of reports and you want the user to select a few of those reports and post back to your controller. So that you can generate reports for the selected report names? – Kosala W Dec 21 '15 at 05:23
  • @Kosala yes I want to pass only selected reports from view to controller..but hidden field values also going as string to controller and binded in model.reports. i want to skip the hidden fields going to controller – SivaRajini Dec 21 '15 at 05:31
  • @stephen so when i use Ienumerbale it will pass both checkbox value and hidden field value to controller ? can't we avoid the skipping the hidden field value – SivaRajini Dec 21 '15 at 05:32
  • As per my last comment, just generate the html manually. The `CheckBox()` method is for binding to a `bool`. Since your not binding to a `bool`, then don't use it. –  Dec 21 '15 at 06:00

2 Answers2

2

First of all, you need a viewModel for the report;

public class Report
{
    public string ReportName { get; set; }
    public bool IsSelected { get; set; }
}

Then let's assume you are using your "Home" controller for this. Go to Home folder which is under Views in your project.

Create a new Folder called DisplayTemplates. This name and folder position is extremely important. So use the exact name.

Then create a new view inside DisplayTemplates. The name of your view has to be Report.cshtml.

In Report.cshtml view, use the below code;

model MvcApplication1.Models.Report

@Html.CheckBoxFor(m=>m.IsSelected)
@Html.Label(Model.ReportName, Model.ReportName)

Then go back in to Home view folder and select Index.cshtml. Add below code to index page.

@model List<MvcApplication1.Models.Report>

@using (Html.BeginForm("ShowReports", "Home", Model, FormMethod.Post))
{
     @Html.DisplayFor(m => m)

    <button type="submit">Show Selected Reports</button>
}

Now add below code to HomeController.

    public ActionResult Index()
    {
        List<Report> reports = new List<Report>()
        {
            new Report(){ReportName = "Report 1", IsSelected = false},
            new Report(){ReportName = "Report 2", IsSelected = false},
            new Report(){ReportName = "Report 3", IsSelected = false},
            new Report(){ReportName = "Report 4", IsSelected = false},
            new Report(){ReportName = "Report 5", IsSelected = false},
        };
        return View(reports);
    }

    public ActionResult ShowReports(IEnumerable<Report> model)
    {
        Debug.Write(model.Count());
        return View(); //create a blank view called ShowReport.
    }

Add a break point to ShowReport and have a look at what you are getting for the model variable.

Kosala W
  • 2,133
  • 1
  • 15
  • 20
1

You can use the CheckBoxFor(x=>x) helper if you have that option available. I was creating a form which was self generating and I need didn't have a hardcoded model to build the form from.

So to fix this issue, I looked at the result and if the checkbox was being submitted checked it would return two values (true/false) like you stated. if the check box wasn't checked it would submit only false, the hidden value.

There was other ways people where suggesting using javascript, but what if javascript was disabled? So i decided to use this in the controller which receives a form collection.

public ActionResult methodName (FormCollection collecitonName)
        {
            foreach (var key in collecitonName.AllKeys)
            {
                var isCheckboxTrue = Request.Form[key].Contains("true")
            }
         }
Joshua Duxbury
  • 4,892
  • 4
  • 32
  • 51