开发者

MVC map to nullable bool in model

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 t开发者_StackOverflowhe 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.


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.


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...


To me, this is a lot better:

<%= Html.CheckBox("IsDefault", Model.IsDefault.HasValue? Model.IsDefault : false) %>


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.


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) %>


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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜