ModelState.IsValid == false, por que?

120

Onde posso encontrar a lista de erros que inviabilizam o ModelState? Não vi nenhuma propriedade de erros no objeto ModelState.

Omu
fonte

Respostas:

45

Sobre "pode ​​ser que 0 erros e IsValid == false": aqui está o código-fonte do MVC em 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);
    }
}

Agora, parece que não pode ser. Bem, isso é para o ASP.NET MVC v1.

queen3
fonte
parece-me que não deveria, há algo errado em Values.All (modelState => modelState.Errors.Count == 0)?
Omu
Observe que o erro pode ser Mensagem ou Exceção; por exemplo, Html.ValidationSummary não exibe exceções (por razões de segurança, eu acho); talvez seja por isso que você não vê erros? Como você verifica se não há erros?
queen3
1
ModelState.IsValid fornece false
Omu
Ha-ha, isso é óbvio ... como você verifica "os valores têm 0 erros"?
queen3
258

Como você provavelmente está programando no Visual studio, é melhor aproveitar a possibilidade de usar pontos de interrupção para etapas tão fáceis de depuração (tendo uma idéia de qual é o problema no seu caso). Basta colocá-los em frente / no local em que você verifica ModelState.isValid e passa o mouse sobre o ModelState. Agora você pode navegar facilmente por todos os valores internos e ver qual erro causa o retorno isvalid false.

modelstate

bastijn
fonte
3
seria possível que todos os valores tivessem 0 erros e o estado do modelo ainda fosse inválido?
Omu
como dito acima, não, isso não é possível :). Em algum lugar deve haver uma contagem de erros! = 0.
bastijn 24/11/2009
2
Como complemento, se o ErrorMessage for ambíguo para você, você poderá acessar as teclas e ele mostrará a qual variável está se referindo.
Luminous
1
no seu modo de exibição, faça: @ Html.HiddenFor (model => model.Username) resolverá o problema!
Umit Kaya
1
var asdf = ModelState.Values.Where(v => v.Errors.Count > 0);pode ajudá-lo
Cirelli94
37

Cole o código abaixo no ActionResult do seu controlador e coloque o depurador neste momento.

var errors = ModelState
    .Where(x => x.Value.Errors.Count > 0)
    .Select(x => new { x.Key, x.Value.Errors })
    .ToArray();
Krishna
fonte
3
A melhor resposta aqui deve ser classificada como mais alta. Por que gastar meu tempo vasculhando 5 camadas do objeto ModelState no depurador quando eu posso obter os erros dele? Eu estaria lá durante toda a manhã se eu tivesse seguido o maior resposta nominal
Sean T
2
este é o melhor de todos os tempos
brinquedo
23
bool hasErrors =  ViewData.ModelState.Values.Any(x => x.Errors.Count > 1);

ou itere com

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

    }
Michael G
fonte
seria possível que todos os valores tivessem 0 erros e o estado do modelo ainda fosse inválido?
Omu
1
O estado de modelo terá uma chave "Propriedade" e um erro associado no dicionário. a mensagem de erro pode estar em branco, mas a contagem de erros refletirá a contagem de propriedades inválidas. Como o método ModelStateDictionary.AddModelError recebe uma chave e Exception or error String; é necessário adicionar um erro de modelo.
Michael G
13

Às vezes, um fichário lança uma exceção sem mensagem de erro. Você pode recuperar a exceção com o seguinte snippet para descobrir o que está errado:

(Geralmente, se o fichário estiver tentando converter seqüências de caracteres em tipos complexos, etc.)

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

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

  }
Jonas Stensved
fonte
1
Esse código foi muito útil para mim, mas a iteração dos erros (exceções) para obter cada. Mensagem resultou em "referência de objeto não definida para uma instância de um objeto". Quando mudei z.Exception para z.ErrorMessage, pude exibir as mensagens de erro.
precisa
Esta foi a solução para mim, alterando para z.ErrorMessage, embora não tenha recebido um erro com z.Exception, apenas valores nulos. Provavelmente vale a pena atualizar a resposta original.
esp
5

Se você remover a verificação de ModelsState.IsValid e deixar que isso ocorra, se você copiar esta linha ((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrorse colar na seção de exibição no Visual Studio, ele fornecerá exatamente qual é o erro. Economiza muito tempo verificando onde está o erro.

Tom McDonough
fonte
1
Dica realmente útil.
Ash
Este é o melhor conselho neste tópico. O problema que tive foi um "estúpido". (ponto) em UserName
mangia
3

A propriedade ModelState no controlador é realmente um objeto ModelStateDictionary. Você pode percorrer as chaves no dicionário e usar o método IsValidField para verificar se esse campo específico é válido.

tvanfosson
fonte
3

Como aconteceu comigo - isso também pode acontecer quando você adiciona uma propriedade necessária ao seu modelo sem atualizar seu formulário. Nesse caso, o ValidationSummary não listará a mensagem de erro.

AndyP9
fonte
1
Isso aconteceu comigo. Obrigado pela dica!
Lewis86