Comment gérer Booleans / CheckBox dans ASP.NET MVC 2 avec DataAnnotations?

J’ai un modèle de vue comme celui-ci:

public class SignUpViewModel { [Required(ErrorMessage = "Bitte lesen und akzeptieren Sie die AGB.")] [DisplayName("Ich habe die AGB gelesen und akzeptiere diese.")] public bool AgreesWithTerms { get; set; } } 

Le code de balisage de la vue:

  m.AgreesWithTerms) %>  m.AgreesWithTerms)%> 

Le résultat:

Aucune validation n’est exécutée. Ce n’est pas grave, car bool est un type de valeur et jamais nul. Mais même si je rends AgreesWithTerms nullable, cela ne fonctionnera pas car le compilateur crie

“Les modèles ne peuvent être utilisés qu’avec l’access aux champs, l’access aux propriétés, l’index de tableau à une seule dimension ou les expressions d’indexeur personnalisées à un seul paramètre.”

Alors, quelle est la bonne façon de gérer cela?

Ma solution est la suivante (ce n’est pas très différent des réponses déjà soumises, mais je crois que c’est mieux nommé):

 ///  /// Validation atsortingbute that demands that a boolean value must be true. ///  [AtsortingbuteUsage(AtsortingbuteTargets.Property, AllowMultiple = false, Inherited = false)] public class MustBeTrueAtsortingbute : ValidationAtsortingbute { public override bool IsValid(object value) { return value != null && value is bool && (bool)value; } } 

Ensuite, vous pouvez l’utiliser comme ça dans votre modèle:

 [MustBeTrue(ErrorMessage = "You must accept the terms and conditions")] [DisplayName("Accept terms and conditions")] public bool AcceptsTerms { get; set; } 

Je créerais un validateur à la fois du côté serveur et du côté client. En utilisant MVC et la validation de forme non intrusive, ceci peut être réalisé simplement en procédant comme suit:

Tout d’abord, créez une classe dans votre projet pour effectuer la validation côté serveur comme suit:

 public class EnforceTrueAtsortingbute : ValidationAtsortingbute, IClientValidatable { public override bool IsValid(object value) { if (value == null) return false; if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties."); return (bool)value == true; } public override ssortingng FormatErrorMessage(ssortingng name) { return "The " + name + " field must be checked in order to continue."; } public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { yield return new ModelClientValidationRule { ErrorMessage = Ssortingng.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage, ValidationType = "enforcetrue" }; } } 

Ensuite, annotez la propriété appropriée dans votre modèle:

 [EnforceTrue(ErrorMessage=@"Error Message")] public bool ThisMustBeTrue{ get; set; } 

Et enfin, activez la validation côté client en ajoutant le script suivant à votre vue:

  

Note: Nous avons déjà créé une méthode GetClientValidationRules qui pousse notre annotation à la vue depuis notre modèle.

Je l’ai eu en créant un atsortingbut personnalisé:

 public class BooleanRequiredAtsortingbute : RequiredAtsortingbute { public override bool IsValid(object value) { return value != null && (bool) value; } } 
 [Compare("Remember", ErrorMessage = "You must accept the terms and conditions")] public bool Remember { get; set; } 

Cela pourrait être un “hack” mais vous pouvez utiliser l’atsortingbut Range intégré:

 [Display(Name = "Accepted Terms Of Service")] [Range(typeof(bool), "true", "true")] public bool Terms { get; set; } 

Le seul problème est que la chaîne “warning” indiquera “Le FIELDNAME doit être entre True et true”.

“Required” est la mauvaise validation, ici. Vous voulez quelque chose qui ressemble à “Doit avoir la valeur true”, ce qui n’est pas la même chose que “Required”. Qu’en est-il de l’utilisation de quelque chose comme:

 [RegularExpression("^true")] 

?

Ma solution est cet atsortingbut personnalisé simple pour les valeurs booléennes:

 public class BooleanAtsortingbute : ValidationAtsortingbute { public bool Value { get; set; } public override bool IsValid(object value) { return value != null && value is bool && (bool)value == Value; } } 

Ensuite, vous pouvez l’utiliser comme ça dans votre modèle:

 [Required] [Boolean(Value = true, ErrorMessage = "You must accept the terms and conditions")] [DisplayName("Accept terms and conditions")] public bool AcceptsTerms { get; set; } 

Je prends simplement le meilleur des solutions existantes et je les rassemble en une seule réponse qui permet la validation côté serveur et côté client.

Le pour appliquer pour modéliser une propriété pour garantir qu’une valeur booléenne doit être vraie:

 ///  /// Validation atsortingbute that demands that a  value must be true. ///  /// Thank you http://stackoverflow.com/a/22511718 [AtsortingbuteUsage(AtsortingbuteTargets.Property, AllowMultiple = false, Inherited = false)] public class MustBeTrueAtsortingbute : ValidationAtsortingbute, IClientValidatable { ///  /// Initializes a new instance of the  class. ///  public MustBeTrueAtsortingbute() : base(() => "The field {0} must be checked.") { } ///  /// Checks to see if the given object in  is true. ///  /// The value to check. /// true if the object is a  and true; otherwise false. public override bool IsValid(object value) { return (value as bool?).GetValueOrDefault(); } ///  /// Returns client validation rules for  values that must be true. ///  /// The model metadata. /// The controller context. /// The client validation rules for this validator. public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { if (metadata == null) throw new ArgumentNullException("metadata"); if (context == null) throw new ArgumentNullException("context"); yield return new ModelClientValidationRule { ErrorMessage = FormatErrorMessage(metadata.DisplayName), ValidationType = "mustbetrue", }; } } 

Le JavaScript à inclure pour utiliser la validation discrète.

 jQuery.validator.addMethod("mustbetrue", function (value, element) { return element.checked; }); jQuery.validator.unobtrusive.adapters.addBool("mustbetrue"); 

Pour les personnes qui rencontrent des difficultés pour que cela fonctionne pour la validation du côté client (anciennement moi): assurez-vous d’avoir aussi

  1. Inclus <% Html.EnableClientValidation (); %> avant le formulaire dans la vue
  2. Utilisé <% = Html.ValidationMessage ou Html.ValidationMessageFor pour le champ
  3. Création d’un DataAnnotationsModelValidator qui renvoie une règle avec un type de validation personnalisé
  4. Enregistré la classe dérivée de DataAnnotationsModelValidator dans le Global.Application_Start

http://www.highoncoding.com/Articles/729_Creating_Custom_Client_Side_Validation_in_ASP_NET_MVC_2_0.aspx

est un bon tutoriel pour faire cela, mais manque l’étape 4.

La bonne façon de faire est de vérifier le type!

 [Range(typeof(bool), "true", "true", ErrorMessage = "You must or else!")] public bool AgreesWithTerms { get; set; } 

Nous avons trouvé une solution plus complète ici (validation côté serveur et côté client):

http://blog.degree.no/2012/03/validation-of-required-checkbox-in-asp-net-mvc/#comments

Il suffit d’append [RegularExpression]:

 [DisplayName("I accept terms and conditions")] [RegularExpression("True", ErrorMessage = "You must accept the terms and conditions")] public bool AgreesWithTerms { get; set; } 

Note – “True” doit commencer par T majuscule