2010-10-19 4 views
4

Je suis en train de me familiariser avec les attributs de validation personnalisés, et j'essaye d'écrire un attirbute de validation personnalisé qui sera placé au niveau de la classe pour valider par rapport à plusieurs propriétés de mon modèle.Comment définir plusieurs messages d'erreur pour différents scénarios dans un attribut de validation personnalisé?

Je peux accéder à toutes les propriétés de mon modèle, et je veux être capable de vérifier plusieurs conditions dans ma surcharge IsValid, et de les rapporter, en ayant différents messages d'erreur comme suit (exemple simpliste).

public override bool IsValid(object value) 
    { 
     var model = (MyObject) value; 

     //if this value is set, I don't want to do anything other checks 
     if (model.Prop3) 
     { 
      return true; 
     } 

     if (model.Prop1 == "blah" && model.Prop2 == 1) 
     { 
      ErrorMessage = "you can't enter blah if prop 2 equals 1"; 
      return false; 
     } 

     if(model.Prop1 == "blah blah" && model.Prop2 == 2) 
     { 
      ErrorMessage = "you can't enter blah blah if prop 2 equals 2"; 
      return false; 
     } 


     return true; 
    } 

Mais quand je fais ce que je reçois une exception sur la première fois ErrorMessage est référencé « Impossible de définir la propriété plus d'une fois.

Maintenant, je pouvais partager mon attribut personnalisé en plusieurs attributs personnalisés, mais il espère il y aurait une façon de le faire en un seul, sinon, je vais répéter mon « fourre-tout » dans chaque

//if this value is set, I don't want to do anything other checks 
     if (model.Prop3) 
     { 
      return true; 
     } 

J'ai eu une recherche déjà, mais n'a pas pu trouver quoi que ce soit, donc mes excuses si Il me manque quelque chose d'évident:

merci d'avance!

Répondre

1

Question intéressante! Je peux penser à deux solutions à ce problème. Donc, pas de bonnes solutions basées sur ce que vous voulez, mais ils pourraient aider à réutiliser votre code. Cant vous créez une classe abstraite CustomAttribute appelé MyCustomAttribute (ou quelque chose) qui l'emporte sur IsValid de la manière suivante:

public override bool IsValid(object value) 
{ 
    var model = (MyObject) value; 

    //if this value is set, I don't want to do anything other checks 
    if (model.Prop3) 
    { 
     return true; 
    } 

    CustomValidate(model); 
} 

CustomValidate(MyObject model) est votre méthode abstraite puis, vous pouvez écrire plusieurs attribut personnalisé des classes qui étendent MyCustomAttribute et purement doivent mettre en œuvre la logique de validation pour un scénario particulier.

donc vous pouvez avoir deux classes:

public class BlahCustomAttribute : MyCustomAttribute 
{ 
    public override Boolean CustomValidate(MyObject obj) 
    { 
     if (model.Prop1 == "blah" && model.Prop2 == 1) 
     { 
      ErrorMessage = "you can't enter blah if prop 2 equals 1"; 
      return false; 
     } 
    } 
} 

public class BlahBlahCustomAttribute : MyCustomAttribute 
{ 
    public override Boolean CustomValidate(MyObject obj) 
    { 
     if (model.Prop1 == "blah" && model.Prop2 == 1) 
     { 
      ErrorMessage = "you can't enter blah blah if prop 2 equals 1"; 
      return false; 
     } 
    } 
} 

Hope this helps - pas exactement ce que vous vouliez, mais fera le travail et son propre aussi bien.

L'autre solution consiste à séparer par des virgules les messages d'erreur dans la propriété ErrorMessage et à les gérer dans le frontal (mais j'irais avec la première approche).

3

En MVC4 vous pouvez remplacer IsValid retourner différents messages comme ValidationResult

public class StrongPasswordAttribute : ValidationAttribute 
{ 
    protected override ValidationResult IsValid(object value, ValidationContext context) 
    { 
     if (value == null) 
      return new ValidationResult("Password is required"); 

     var val = value.ToString(); 

     if (!Regex.Match(val, @"^(?=.*[a-z]).{0,}$").Success) 
     { 
      return new ValidationResult("Password must contain at least one lower case letter"); 
     } 
     if (!Regex.Match(val, @"^(?=.*[A-Z]).{0,}$").Success) 
     { 
      return new ValidationResult("Password must contain at least one UPPER case letter"); 
     } 
     if (!Regex.Match(val, @"^(?=.*\d).{0,}$").Success) 
     { 
      return new ValidationResult("Password must contain at least one number"); 
     } 

     return ValidationResult.Success; 
    } 
} 
Questions connexes