#c# #asp.net #asp.net-mvc
#c# #asp.net #asp.net-mvc
Вопрос:
Предположим, у нас есть модель со свойством WillMarry
bool?
типа. Мы можем неявно вызывать все следующие действия без каких-либо проблем.
obj.WillMarry=null;
obj.WillMarry=false;
obj.WillMarry=true;
Теперь рассмотрим следующее ASP.NET Страница просмотра MVC.
<select asp-for="WillMarry">
<option value="">Choose an option</option>
<option value="true">Yes, I will get married</option>
<option value="false">No, I will not get married</option>
</select>
Привязка модели может заполнять и value="true"
то , и другое , и value="false"
для параметра WillMarry
with ModelState.IsValid
установлено значение true
. Однако он будет установлен ModelState.IsValid
на false
, если я использую value="null"
вместо value=""
.
Вопрос
Если мы можем установить obj.WillMarry=null
неявно, почему привязка модели не может быть установлена WillMarry
на null
via value="null"
и без установки ModelState.IsValid
на false
?
Редактировать
Вероятно, мне придется перефразировать свой вопрос следующим образом.
- Мы можем установить
obj.WillMarry=false
неявно, и связыватель модели также может преобразоватьvalue="false"
вfalse
. - Мы можем установить
obj.WillMarry=true
неявно, и связыватель модели также может преобразоватьvalue="true"
вtrue
. - Мы можем установить
obj.WillMarry=null
неявно, ОДНАКО связыватель модели не может преобразоватьvalue="null"
(вместоvalue=""
) вnull
.
Почему существует такое странное поведение в привязке модели только для null
?
Ответ №1:
Когда вы отправляете форму, вы отправляете имя / значение пары его успешных элементов управления в запросе. Если вы выберете первый вариант с value="null"
(а value=""
не с), он отправит WillMarry: null
.
Все, что отправляется в запросе, — это просто текст (понятия типов не существует), и ответственность за DefaultModelBinder
преобразование значений в тип свойства лежит на нем. В вашем случае DefaultModelBinder
находит соответствующее имя свойства в вашей модели (свойство, которое есть public bool? WillMarry { get; set; }
) и пытается установить его путем преобразования текста "null"
в a boolean
, который завершается с ошибкой и ModelState
становится недействительным.
Для представления a null
отправляемое значение должно быть пустой строкой.
Комментарии:
1. Учитывая, что мы можем делать
obj.WillMarry=null;
неявно, почему связующее значение модели не может"null"
быть преобразовано в логическое значение с нулевым значением?2. Потому что текст «null» не совпадает с
null
. Существует разница междуbool? WillMarry = null;
иbool? WillMarry = "null";
. Изображение у вас есть свойство, которое является typeof string, и вы разместили значение «null» — ожидаете ли выDefaultModelBinder
, что для свойства будет установленоnull
значение или значение «null» 🙂3. С тем же мышлением,
obj.WillMarry=false
это не то же самое, чтоWillMarry="false"
но model binder может сделать это без каких-либо проблем, верно?4. Потому
DefaultModelBinder
что используются преобразователи значений, а «false» преобразуется вfalse
. Я не могу использовать преобразователь значений для преобразования «null» вnull
из-за примера, который я использовал выше. Если вы хотите изучить исходный код, вы можете найти его здесь5. связующее звено модели было построено таким образом, чтобы оно могло преобразовывать «» в
null
для обнуляемого bool, что имеет смысл. преобразование «null» вnull
, возможно, имело бы смысл для c #, но рассмотрим, например, тот же код, написанный на VB.Net . Должен ли код преобразовывать «null», «Nothing» и все, что используется какnull
в любом сетевом языке, вnull
? Я согласен с реализацией, которую они сделали дляDefaultModelBinder
Ответ №2:
После вашей правки я перепечатываю свой комментарий в качестве ответа:
связующее звено модели было построено таким образом, чтобы оно могло преобразовывать «» в null
для обнуляемого bool, что имеет смысл.
Преобразование «null» в null
, возможно, имело бы смысл для c #, но рассмотрим, например, тот же код, написанный на VB.Net .
Должен ли код преобразовывать «null», «Nothing» и все, что используется как null
в любом сетевом языке, в null
?
Я согласен с реализацией, которую они сделали для DefaultModelBinder
Комментарии:
1. Является ли Razor механизмом просмотра, зависящим от конкретного языка? Одна страница просмотра не может использовать более одного языка, не так ли? Если да, то для программиста на c #
value="null"
имеет смысл и для vb.net программистvalue="nothing"
имеет смысл.2. @SingleFighter Код DefaultModelBinder не зависит от языка, с которого вызывается. Он ведет себя точно так же, если он вызывается анализатором Razor, кодом c #, кодом vb и т. Д., Разработчики сети решили разрешить преобразование из «» в null и не разрешать преобразование из «null», «Nothing» или чего-либо еще в null. Для меня это был правильный выбор.