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.

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.


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


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();

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))
    {

    }

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.

  }

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.


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.


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.


1
Isso aconteceu comigo. Obrigado pela dica!
Lewis86
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.