问题
With a view model containing the field:
public bool? IsDefault { get; set; }
I get an error when trying to map in the view:
<%= Html.CheckBoxFor(model => model.IsDefault) %>
Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)
I've tried casting, and using .Value
and neither worked.
Note the behaviour I would like is that submitting the form should set IsDefault
in the model to true or false. A value of null
simply means that the model has not been populated.
回答1:
The issue is you really have three possible values; true, false and null, so the the CheckBoxFor cannot handle the three states (only two states).
Brad Wilson discusses on his blog here. He uses a DropDownList for nullable booleans.
This StackOverflow question does a much better job of describing the situation than I did above. The downside to the solution is sometimes nullable does not imply false, it should be nullable. An example of this would be filter criteria where you don't want true or false applied.
回答2:
If you don't care about the null value, and just want the checkbox to be unchecked when its null, you can do the following:
Create another property of type bool in your Model like this:
public bool NotNullableBool
{
get
{
return NullableBool == true;
}
set
{
NullableBool = value;
}
}
Then just use that for binding...
回答3:
To me, this is a lot better:
<%= Html.CheckBox("IsDefault", Model.IsDefault.HasValue? Model.IsDefault : false) %>
回答4:
Here's how to map a bullable boolean bool?
property in a DropDownListFor
:
@model SomeModel
<!-- ...some HTML... -->
@Html.DropDownListFor(m => m.NullableBooleanProperty, new SelectList(
new[] {
new { Value = "", Text = "-- Choose YES or NO --" },
new { Value = "true", Text = "YES" },
new { Value = "false", Text = "NO" },
},
"Value",
"Text"
))
And here's how to map it to a CheckBoxFor
by using a non-nullable proxy property as a workaround:
In the ViewModel:
public bool NullableBooleanPropertyProxy
{
get
{
return NullableBooleanProperty == true;
}
set
{
NullableBooleanProperty = value;
}
}
In the View:
@model SomeModel
<!-- ...some HTML... -->
@Html.CheckBoxFor(m => m.NullableBooleanPropertyProxy)
The only downside of this workaround is that the null
value will be treated as false
: if you can't accept that, it's better to use a control that can support three states, such as the aforementioned DropDownListFor
.
For further info, read this post on my blog.
回答5:
To add to vapcguy answer, another more "cleaner" way to do it is like follows
@Html.CheckBox("IsDefault", Model?.IsDefault)
Or
<%= Html.CheckBox("IsDefault", Model?.IsDefault) %>
回答6:
You can create an editor template to render a checkbox for nullable Booleans. Name the template Boolean.cshtml to use it as the default for all of the Boolean properties within the site. Ensure that the file is in the folder ~/Views/Shared/EditorTemplates
@model bool?
@Html.CheckBox(String.Empty, Model??false)
来源:https://stackoverflow.com/questions/3035957/mvc-map-to-nullable-bool-in-model