0

On my MVC View I have a few checkboxes:

<form method="POST" id="formRegistration" action="Registration/SubmitRegistration" > 
//Other code...
    <input name="test1" type="checkbox" />
    <input name="test2" type="checkbox"  />
</form>

On the controller I get- using a POST request- the data and I insert it to the DataBase:

public void AddRegistered(Registration r)
{
//Other code...
     dParameters.Add("test1", r.test1.ToString());
     dParameters.Add("test2", r.test2.ToString());
//Other code...
}

The problem is that I keep getting a false value even if the checkbox is checked.

Wham am I missing?

16
  • Use Html.CheckBoxFor instead of using manual HTML. Commented Mar 5, 2017 at 21:39
  • It's a requirement to use manual HTML, I can't use Razor. Commented Mar 5, 2017 at 21:40
  • A checkbox post back the value of its control is checked (or nothing if not checked. Your setting value="false" so all it can ever submit is false. And if you not gong to use the HtmlHelper methods, then don't bother using mvc since you will never get correct model binding. Commented Mar 5, 2017 at 21:48
  • Sorry, I forgot to delete the value="false" it was one of my testings, would you be able to explain more what you mean by: And if you not gong to use the HtmlHelper methods, then don't bother using mvc since you will never get correct model binding. It's very important for me to fully understand what you mean. Thanks! Commented Mar 5, 2017 at 21:53
  • 2
    @StephenMuecke: I generate manual forms in ASP.Net all the time, not to mention post into MVC controllers using javascript etc. Saying that the only thing that can post data into MVC is HtmlHelper is naive. Commented Mar 5, 2017 at 21:53

3 Answers 3

1

So the first thing you should do it take a look at the actual data being sent to the server with chrome debug tools or similar. What you might find is that your checkbox value will be set to on if checked, or it will be missing completely if un-checked.

One suggestion in the comments was @Html.CheckBoxFor, but this also suffers the fact that nothing will be sent if the checkbox is un-checked and in specific situations that can still become a problem.

You have two solutions - fix it on the client, or fix it on the server.

Fix it on the client:
To do this, you'll need to (with javascript) add a hidden field for every checkbox. Forgive me, I'm not by an editor to test it out but it might look something like this (from memory):

$('input[type="checkbox"]').each(function(el) {
    var hidden = $('<input type="hidden" />');
    hidden.name = el.name;
    el.after(hidden);
    el.on("change", function(el) {
       hidden.value = el.checked ? "true" : "false";
    });
});

Fix it on the server:
To do this, you'll need to create a custom PropertyBinder which recognizes on as a boolean true. This would be set on a property-attribute level. You could alternatively override the global ModelBinder to do this so you don't need to specifically annotate a property for this to work.


Personally, I prefer the "fix it on the client" method, because you will get either true or false posted back to the server every time which is what you'd expect and is the closest to the way that HtmlHelper does it.

Sign up to request clarification or add additional context in comments.

2 Comments

nothing will be sent if the checkbox is un-checked is simply wrong! - @Html.CheckBoxFor() correctly generates 2 inputs, a checkbox with Value="True and a hidden input with value="False"
Maybe you're right about that, I can't check right now - but I've had to ditch HtmlHelper and do this manually before because I wasn't getting false values posted back to the server. Could be a separate issue, not sure.
1

You are missing the value attribute:

<input name="test1" type="checkbox" value="true" />
<input name="test2" type="checkbox" value="true" />

As simple as that.

Comments

1

If you don't want to use HtmlHelper class you can do like this

<form method="POST" id="formRegistration" action="Registration/SubmitRegistration" > 

<input name="test1" type="checkbox" value="@Model.test1" />
<input name="test2" type="checkbox" value="@Model.test2"  />

test1 and test2 should be in your model class.

1 Comment

You can also do <input name="@( nameof(@Model.test1 ) )" /> as well - though this won't work for nested/child views or complex view-models.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.