find a location for property in a new city

Saturday, 13 August 2011

ASP.NET MVC Checkbox has a hidden input too

I noticed strange behaviour whilst coding and ASP.NET MVC CheckBox Html Helper. I noticed that the field which was in part of a GET form was creating the query string with the same field in it twice. When the box was checked one parameter was true and the other was false.

Say I have a boolean field, MyField, that I am creating a checkbox for. I would write this: @Html.CheckBox("MyField"). You would expect this to output a single check box but if you actually look at the HTML that is generated you will notice that is also creates a hidden field.



I found out the the reason for this is written within the ASP.NET MVC source code:
if (inputType == InputType.CheckBox) {
    // Render an additional  for checkboxes. This
    // addresses scenarios where unchecked checkboxes are not sent in the request.
    // Sending a hidden input makes it possible to know that the checkbox was present
    // on the page when the request was submitted.
    StringBuilder inputItemBuilder = new StringBuilder();
    inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));

    TagBuilder hiddenInput = new TagBuilder("input");
    hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
    hiddenInput.MergeAttribute("name", name);
    hiddenInput.MergeAttribute("value", "false");
    inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
    return inputItemBuilder.ToString();
}

I appreciate the reasoning behind this but in my scenario MyField is part of a ViewModel that is being sent with the form and of course boolean values are False by default so this is wasted on my scenario.

Another reason I do not like this is because I am using the GET method on my form the user will see this oddity in the querystring. Worse still, they be a developer and judge my code as rubbish not knowing it is the doing of ASP.NET MVC. I can't have that! ;)

Solution

Simple solution really. Write the HTML you want in HTML, forget about the HtmlHelper:
<input type="checkbox" name="MyField" value="true" id="MyField"
@Html.Raw((Model.MyField) ? "checked=\"checked\"" : "") />

Remember the value="true" because the default value to be sent is "on" if it is checked, which obviously can't be parsed to a Boolean.

Obviously, this doesn't look that clean but I will continue to do this on forms that use the GET method.

Follow britishdev on Twitter

7 comments:

  1. You, sir, just helped me out of 3-hrs nightmare hunt. Thank you!

    ReplyDelete
  2. Thanks, was pulling my hair out over this!

    ReplyDelete
  3. Thank you! Thank you! Thank you! This was spot on and solved my problem

    ReplyDelete
  4. Many Many thanks. Now my problem is resolved.
    I was wasting 2-3 hr every night since 1 week and now my issue is resolved. It's really great.

    ReplyDelete