Что такое ModelState.IsValid для ASP.NET MVC в NerdDinner?

148

На примере NerdDinner Professional ASP.NET MVC 1.0 есть метод для создания нового обеда в виде скопированного ниже (стр. 89 бесплатной версии NerdDinner).

Там он проверяет ModelState.IsValid на true. Кажется, он проверяет, является ли модель действительной для базы данных (то есть она улавливает преобразования типов данных, например даты с недопустимым форматом, но не бизнес-правила). Это правда?

При отправке формы, если у вас есть ошибка в дате, ModelState.IsValid будет иметь значение false, и вы получите ошибку, но только для даты, потому что AddRuleViolations никогда не выполнялась. Если вы полностью удалите проверку ModelState.IsValid, вы получите все ошибки (из-за исключения), включая отметку в дате, когда она недействительна. Тогда зачем вообще проверять ModelState.IsValid? Я что-то упускаю?

// 
// POST: /Dinners/Create 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Dinner dinner) {
    if (ModelState.IsValid) {
        try {
            dinner.HostedBy = "SomeUser"; 

            dinnerRepository.Add(dinner);
            dinnerRepository.Save();

            return RedirectToAction("Details", new {id = dinner.DinnerID }); 
        } catch {
            ModelState.AddRuleViolations(dinner.GetRuleViolations());
        } 
    } 
    return View(dinner); 
} 
pupeno
источник

Ответы:

143

ModelState.IsValidсообщает, были ли добавлены какие-либо ошибки модели ModelState.

Связыватель модели по умолчанию добавит некоторые ошибки для основных проблем преобразования типов (например, передача не-числа для чего-то, что является "int"). Вы можете заполнить ModelState более полно в зависимости от используемой вами системы валидации.

Привязка образца DataAnnotationsмодели заполнит состояние модели ошибками проверки, взятыми из DataAnnotationsатрибутов вашей модели.

Брэд Уилсон
источник
У Брэда есть какой-нибудь способ выяснить, украшена ли модель с аннотациями данных "IsValid" без ModelState. (Скажем, например, что объект загружен из файла или используется в консольном приложении и т. Д.)
runxc1 Брет Ферье
1
Нет, ModelState.IsValid - это единственный способ узнать, были ли какие-либо ошибки проверки (или преобразования данных) во время привязки модели.
Брэд Уилсон
@Brad, когда вы говорите: «Вы можете заполнить ModelState более полно на основе используемой вами системы проверки», как это достигается? Есть ли способ взломать мой код проверки ModelState для моей ViewModel? Я использую EF4, так что большая часть моей проверки происходит автоматически из коробки.
WEFX
13
Использование: var errors = ModelState.Values.SelectMany(v => v.Errors);с точкой останова для просмотра любых вопросов проверки.
full_prog_full
Иногда это ошибка в связанной таблице, если имена свойств были изменены, миграции не были выполнены, и в результате SaveChanges (); отказывает и не может произойти из-за изменения.
Оракулярный человек
25

Из опечаток: ModelState.AddRuleViolations(dinner.GetRuleViolations());

Должно быть:

ModelState.AddModelErrors(dinner.GetRuleViolations());

Ссылка: http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-MVC-1-0.productCd-0470384611,descCd-ERRATA.html

Келли Орр
источник
5
По состоянию на 2015 год AddModelErrorsметод не существует.
Фелипе Корреа
6
По состоянию на 2016 год ModelState.AddModelErrors()метод существует
Джон
7
По состоянию на 2017 год существует не множественный ModelState.AddModelErrorметод.
Захафер
0

Да, Джаред и Келли Орр правы. Я использую следующий код, как в редактировании исключения.

foreach (var issue in dinner.GetRuleViolations())
{
    ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}

вместо того

ModelState.AddRuleViolations(dinner.GetRuleViolations());
Фо Хто
источник
0

Все поля модели, которые имеют определенные типы, должны быть проверены при возврате в Controller. Если какое-либо из полей модели не соответствует их определенному типу, то ModelState.IsValid вернет false. Потому что эти ошибки будут добавлены в ModelState.

B.Khan
источник