ModelState.IsValid == false, почему?

120

Где я могу найти список ошибок, из-за которых ModelState становится недействительной? Я не видел никаких ошибок в объекте ModelState.

Ома
источник

Ответы:

45

О том, «может ли быть 0 ошибок и IsValid == false»: вот исходный код MVC из https://github.com/Microsoft/referencesource/blob/master/System.Web/ModelBinding/ModelStateDictionary.cs#L37-L41

public bool IsValid {
    get {
        return Values.All(modelState => modelState.Errors.Count == 0);
    }
}

Теперь похоже, что этого не может быть. Что ж, это для ASP.NET MVC v1.

queen3
источник
мне кажется, что не должно, что-то не так в Values.All (modelState => modelState.Errors.Count == 0)?
Omu
Обратите внимание, что ошибка может быть сообщением или исключением; например, Html.ValidationSummary не отображает исключения (полагаю, из соображений безопасности); может поэтому вы не видите ошибок? Как вы проверяете отсутствие ошибок?
queen3
1
ModelState.IsValid дает false
Ому
Ха-ха, это очевидно ... как вы проверяете, что "значения содержат 0 ошибок"?
queen3
258

Поскольку вы, вероятно, программируете в Visual Studio, вам лучше воспользоваться возможностью использования точек останова для таких простых шагов отладки (чтобы понять, в чем проблема, как в вашем случае). Просто поместите их прямо перед / в том месте, где вы проверяете ModelState.isValid, и наведите курсор на ModelState. Теперь вы можете легко просмотреть все значения внутри и увидеть, какая ошибка вызывает isvalid return false.

ModelState

bastijn
источник
3
Возможно ли, что все значения имеют 0 ошибок, а состояние модели все еще недействительно?
Omu
как сказано выше, это невозможно :). Где-то должно быть количество ошибок! = 0.
bastijn
2
В качестве дополнения, если ErrorMessage неоднозначен для вас, вы можете перейти к клавишам, и они покажут вам, к какой переменной относится.
Luminous
1
в вашем представлении выполните: @ Html.HiddenFor (model => model.Username) решит проблему!
Умит Кая
1
var asdf = ModelState.Values.Where(v => v.Errors.Count > 0);могу помочь вам
Cirelli94
37

Вставьте приведенный ниже код в ActionResult вашего контроллера и поместите отладчик в этот момент.

var errors = ModelState
    .Where(x => x.Value.Errors.Count > 0)
    .Select(x => new { x.Key, x.Value.Errors })
    .ToArray();
Кришна
источник
3
Лучший ответ здесь должен быть оценен выше. Зачем тратить время на копание через 5 слоев объекта ModelState в отладчике, если я могу просто избавиться от ошибок. Я был бы там все утро, если бы последовал за ответом с наивысшей оценкой
Шон Т.
2
это лучшая
игрушка
23
bool hasErrors =  ViewData.ModelState.Values.Any(x => x.Errors.Count > 1);

или повторите с

    foreach (ModelState state in ViewData.ModelState.Values.Where(x => x.Errors.Count > 0))
    {

    }
Майкл Дж.
источник
Возможно ли, что все значения имеют 0 ошибок, а состояние модели все еще недействительно?
Omu
1
Состояние модели будет иметь ключ «Свойство» и связанную с ним ошибку в словаре. сообщение об ошибке может быть пустым, но количество ошибок будет отражать количество недействительных свойств. Поскольку метод ModelStateDictionary.AddModelError принимает ключ, а исключение или строка ошибки; требуется добавить ошибку модели.
Michael G
13

Иногда связыватель выдает исключение без сообщения об ошибке. Вы можете получить исключение с помощью следующего фрагмента, чтобы выяснить, что не так:

(Часто, если связыватель пытается преобразовать строки в сложные типы и т. Д.)

 if (!ModelState.IsValid)
            {
var errors = ModelState.SelectMany(x => x.Value.Errors.Select(z => z.Exception));

// Breakpoint, Log or examine the list with Exceptions.

  }
Йонас Стенсвед
источник
1
Этот код был мне очень полезен, но повторение ошибок (исключений) для получения каждого .Message привело к тому, что «ссылка на объект не установлена ​​на экземпляр объекта». Когда я изменил z.Exception на z.ErrorMessage, я смог отобразить сообщения об ошибках.
StackOverflowUser
Это было для меня решением, изменившись на z.ErrorMessage, хотя я не получал ошибки с z.Exception, только нулевые значения. Вероятно, стоит обновить исходный ответ.
esp
5

Если вы удалите проверку для ModelsState.IsValid и допустите ошибку, если вы скопируете эту строку ((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrorsи вставите ее в раздел просмотра в Visual Studio, она точно выдаст вам ошибку. Экономит время, проверяя, где находится ошибка.

Том МакДонаф
источник
1
Действительно полезный совет.
Эш
Это лучший совет в этой ветке. У меня была глупая проблема "." (точка) в UserName
mangia
3

Свойство ModelState на контроллере фактически является объектом ModelStateDictionary. Вы можете перебирать ключи в словаре и использовать метод IsValidField, чтобы проверить, действительно ли это конкретное поле.

tvanfosson
источник
3

Как только что случилось со мной - это также может произойти, когда вы добавляете необходимое свойство в свою модель, не обновляя форму. В этом случае ValidationSummary не будет отображать сообщение об ошибке.

AndyP9
источник
1
Это случилось со мной. Спасибо за чаевые!
Lewis86 01