Como usar anotações de dados para fazer uma validação condicional no modelo?
Por exemplo, digamos que temos o seguinte modelo (Pessoa e Sênior):
public class Person
{
[Required(ErrorMessage = "*")]
public string Name
{
get;
set;
}
public bool IsSenior
{
get;
set;
}
public Senior Senior
{
get;
set;
}
}
public class Senior
{
[Required(ErrorMessage = "*")]//this should be conditional validation, based on the "IsSenior" value
public string Description
{
get;
set;
}
}
E a seguinte visão:
<%= Html.EditorFor(m => m.Name)%>
<%= Html.ValidationMessageFor(m => m.Name)%>
<%= Html.CheckBoxFor(m => m.IsSenior)%>
<%= Html.ValidationMessageFor(m => m.IsSenior)%>
<%= Html.CheckBoxFor(m => m.Senior.Description)%>
<%= Html.ValidationMessageFor(m => m.Senior.Description)%>
Gostaria de ser o campo obrigatório obrigatório da propriedade "Senior.Description" com base na seleção da propriedade "IsSenior" (true -> obrigatório). Como implementar a validação condicional no ASP.NET MVC 2 com anotações de dados?
c#
asp.net-mvc
forms
validation
Peter Stegnar
fonte
fonte
Senior
objeto é sempre um sênior, então por que o IsSenior pode ser falso nesse caso? Você não precisa apenas que a propriedade 'Person.Senior' seja nula quandoPerson.IsSenior
for falsa. Ou por que não implementar aIsSenior
propriedade da seguinte forma:bool IsSenior { get { return this.Senior != null; } }
.Respostas:
Existe uma maneira muito melhor de adicionar regras de validação condicional no MVC3; faça com que seu modelo herde
IValidatableObject
e implemente oValidate
método:Leia mais em Introdução ao ASP.NET MVC 3 (versão 1) .
fonte
ModelState.IsValid
- não chamando Validar diretamenteEu resolvi isso manipulando o dicionário "ModelState" , que está contido pelo controlador. O dicionário ModelState inclui todos os membros que precisam ser validados.
Aqui está a solução:
Se você precisar implementar uma validação condicional com base em algum campo (por exemplo, se A = true, então B for necessário), mantendo as mensagens de erro no nível da propriedade (isso não é verdade para os validadores personalizados que estão no nível do objeto), você pode conseguir isso manipulando "ModelState", simplesmente removendo validações indesejadas dele.
... Em alguma aula ...
... a aula continua ...
... Em alguma ação do controlador ...
...
Com isso, alcançamos a validação condicional, deixando o restante da mesma forma.
ATUALIZAR:
Esta é minha implementação final: usei uma interface no modelo e o atributo action que valida o modelo que implementa a referida interface. A interface prescreve o método Validate (ModelStateDictionary modelState). O atributo em ação apenas chama Validate (modelState) em IValidatorSomething.
Como não queria complicar esta resposta, não mencionei os detalhes finais da implementação (que, no final, são importantes no código de produção).
fonte
Eu tive o mesmo problema ontem, mas o fiz de uma maneira muito limpa, que funciona para a validação do lado do cliente e do servidor.
Condição: com base no valor de outra propriedade no modelo, você deseja criar outra propriedade necessária. Aqui está o código
Aqui PropertyName é a propriedade na qual você deseja tornar sua condição DesiredValue é o valor específico do PropertyName (propriedade) para o qual sua outra propriedade deve ser validada para requerido
Digamos que você tenha o seguinte
Por fim, mas não menos importante, registre o adaptador para o seu atributo para que ele possa fazer a validação do lado do cliente (eu o coloquei em global.asax, Application_Start)
fonte
Eu tenho usado esse nuget incrível que faz anotações dinâmicas ExpressiveAnnotations
Você pode validar qualquer lógica que possa sonhar:
fonte
Você pode desativar validadores condicionalmente removendo erros do ModelState:
fonte
Graças à Merritt :)
Acabei de atualizar isso para o MVC 3, caso alguém ache útil: Validação condicional no ASP.NET MVC 3 .
fonte
Agora existe uma estrutura que faz essa validação condicional (entre outras valiosas validações de anotação de dados) fora da caixa: http://foolproof.codeplex.com/
Especificamente, dê uma olhada no validador [RequiredIfTrue ("IsSenior")]. Você o coloca diretamente na propriedade que deseja validar, para obter o comportamento desejado do erro de validação associado à propriedade "Senior".
Está disponível como um pacote NuGet.
fonte
Você precisa validar no nível Pessoa, não no nível Sênior, ou o Sênior deve ter uma referência à Pessoa pai. Parece-me que você precisa de um mecanismo de auto-validação que defina a validação na Pessoa e não em uma de suas propriedades. Não tenho certeza, mas acho que o DataAnnotations não suporta isso imediatamente. O que você pode fazer para criar o
Attribute
que derivaValidationAttribute
pode ser decorado no nível da classe e, em seguida, criar um validador personalizado que também permita que esses validadores sejam executados.Eu sei que o Bloco de Aplicação de Validação oferece suporte à auto-validação imediata, mas o VAB tem uma curva de aprendizado bastante acentuada. No entanto, aqui está um exemplo usando o VAB:
fonte
Eu tive o mesmo problema, precisava de uma modificação do atributo [Obrigatório] - tornar o campo obrigatório na dependência de solicitação http. A solução foi semelhante à resposta de Dan Hunex, mas sua solução não funcionou corretamente (consulte os comentários). Não uso validação discreta, apenas o MicrosoftMvcValidation.js pronto para uso. Aqui está. Implemente seu atributo personalizado:
Em seguida, você precisa implementar seu provedor personalizado para usá-lo como um adaptador no seu global.asax
E modifique seu global.asax com uma linha
e aqui está
A principal vantagem para mim é que não preciso codificar o validador de cliente personalizado, como no caso de validação discreta. Funciona exatamente como [Necessário], mas apenas nos casos que você deseja.
fonte
DataAnnotationsModelValidator
era exatamente o que eu precisava ver. Obrigado.Confira a Validação Condicional de Simon Ince no MVC .
Estou trabalhando no projeto de exemplo dele agora.
fonte
Uso típico para remoção condicional de erro do Estado do Modelo:
Exemplo:
No seu exemplo, mantenha tudo como está e adicione a lógica sugerida à Ação do seu Controlador. Suponho que seu ViewModel passado para a ação do controlador tenha os objetos Person e Senior Person com dados preenchidos a partir da interface do usuário.
fonte
Estou usando o MVC 5, mas você pode tentar algo como isto:
No seu caso, você diria algo como "IsSenior == true". Então você só precisa verificar a validação da sua ação pós.
fonte