I've encountered an issue with a CheckBox on a page along with the MVC 3 Web Grid. The issue occurs while paging and sorting, giving the following error:
The parameter conversion from type 'System.String' to type 'System.Boolean' failed. See the inner exception for more information.
Investigating the error further it seems the InnerException is:
{"true,false is not a valid value for Boolean."}
It took me a while to find a workable solution and I spent far too long searching on Google for any help on the matter. Fortunately I managed to get it working, and later on in this post I'll give you the answer. Firstly I'll discuss why it occurs.
An Html CheckBox will only post back a value when it is checked, and is ignored when false. This functionality is by design, for good or bad. To compensate for this, a hidden field is created with the same name, and this will post back either true or false. This will give the resulting QueryString:
Unchecked = false.
Checked = true,false.
Slightly odd, but that's the way it is. Let's look at some code.
View Code (cshtml):
@Html.CheckBox("MyBoolValue", @Model.MyBoolValue)
Controller Code:
bool myBoolValue = true;
if (Request.QueryString["MyBoolValue"] != null)
{
myBoolValue = Request.QueryString["MyBoolValue"].Contains("true");
}
What this means is that a value of true,false will be set to true, or otherwise false.
I'd like to state a few more things in case the above doesn't work for you, and in reality my code was slightly different. I separated the name of the CheckBox completely from the value of the model, so my @Model.MyBoolValue was bound to a CheckBox called BoolValue which is what I read back from the query string. In my Controller method I do not use MVC binding, instead using the QueryString to read the value. The issue occurs with the MVC binding which is why I opted to sidestep it completely.
Another option is to create the CheckBox without the Html.CheckBox helper, coding it like so:
<input type="CheckBox" name="MyBoolValue" value="@Model.MyBoolValue"/>
Or you could go a step further and use Custom Model Binding.