Карта MVC для nullable bool в модели
С моделью просмотра, содержащей поле:
public bool? IsDefault { get; set; }
Я получаю сообщение об ошибке при попытке сопоставить в представлении:
<%= Html.CheckBoxFor(model => model.IsDefault) %>
Невозможно неявно преобразовать тип 'bool?' на "bool". Явное преобразование существует (вы пропускаете листинг?)
Я пробовал кастинг и использовал .Value
и не работал.
Обратите внимание, что поведение, которое я хотел бы, заключается в том, что для представления формы следует установить IsDefault
в модели как true или false. Значение null
просто означает, что модель не была заполнена.
Ответы
Ответ 1
Проблема в том, что у вас действительно есть три возможных значения; true, false и null, поэтому CheckBoxFor не может обрабатывать три состояния (только два состояния).
Брэд Уилсон обсуждает в своем блоге здесь. Он использует DropDownList для обнуляемых булевых элементов.
Этот StackOverflow question позволяет намного лучше описать ситуацию, чем я сделал выше. Недостатком решения иногда является значение nullable, которое не подразумевает false, оно должно быть недействительным. Примером этого могут служить критерии фильтрации, в которых вы не хотите применять true или false.
Ответ 2
Если вы не заботитесь о нулевом значении и просто хотите, чтобы флажок не был отмечен при его нулевом значении, вы можете сделать следующее:
Создайте другое свойство типа bool в вашей модели следующим образом:
public bool NotNullableBool
{
get
{
return NullableBool == true;
}
set
{
NullableBool = value;
}
}
Тогда просто используйте это для привязки...
Ответ 3
Для меня это намного лучше:
<%= Html.CheckBox("IsDefault", Model.IsDefault.HasValue? Model.IsDefault : false) %>
Ответ 4
Здесь, как сопоставить булевое логическое свойство bool?
в 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"
))
И вот как сопоставить его с CheckBoxFor
с использованием свойства null-nullable proxy как обходного пути:
В ViewModel:
public bool NullableBooleanPropertyProxy
{
get
{
return NullableBooleanProperty == true;
}
set
{
NullableBooleanProperty = value;
}
}
В представлении:
@model SomeModel
<!-- ...some HTML... -->
@Html.CheckBoxFor(m => m.NullableBooleanPropertyProxy)
Единственным недостатком этого обходного пути является то, что значение null
будет считаться false
: если вы не можете принять это, лучше использовать элемент управления, который может поддерживать три состояния, например вышеупомянутое DropDownListFor
.
Для получения дополнительной информации читайте здесь.
Ответ 5
Чтобы добавить к ответу vapcguy, еще один "более чистый" способ сделать это, как следует
@Html.CheckBox("IsDefault", Model?.IsDefault)
или
<%= Html.CheckBox("IsDefault", Model?.IsDefault) %>
Ответ 6
Вы можете создать шаблон редактора, чтобы отобразить флажок для nullable Booleans. Назовите шаблон Boolean.cshtml, чтобы использовать его как значение по умолчанию для всех логических свойств внутри сайта. Убедитесь, что файл находится в папке ~/Views/Shared/EditorTemplates
@model bool?
@Html.CheckBox(String.Empty, Model??false)