El modelo MVC requiere verdadero

¿Hay alguna forma de anotaciones de datos para exigir que una propiedad booleana se establezca en verdadero?

public class MyAwesomeObj{ public bool ThisMustBeTrue{get;set;} } 

Puede crear su propio validador:

 public class IsTrueAttribute : ValidationAttribute { #region Overrides of ValidationAttribute ///  /// Determines whether the specified value of the object is valid. ///  ///  /// true if the specified value is valid; otherwise, false. ///  /// The value of the specified validation object on which the  is declared. ///  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; } #endregion } 

Crearía un validador para el servidor y el lado del cliente. Usando MVC y validación de forma discreta, esto se puede lograr simplemente haciendo lo siguiente:

En primer lugar, crea una clase en tu proyecto para realizar la validación del lado del servidor de la siguiente manera:

 public class EnforceTrueAttribute : ValidationAttribute, 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 string FormatErrorMessage(string name) { return "The " + name + " field must be checked in order to continue."; } public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { yield return new ModelClientValidationRule { ErrorMessage = String.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage, ValidationType = "enforcetrue" }; } } 

A continuación, anote la propiedad adecuada en su modelo:

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

Y finalmente, habilite la validación del lado del cliente agregando la siguiente secuencia de comandos a su Vista:

  

Nota: Ya creamos un método GetClientValidationRules que empuja nuestra anotación a la vista desde nuestro modelo.

Si utiliza los archivos de recursos para proporcionar el mensaje de error para la internacionalización, elimine la llamada FormatErrorMessage (o simplemente llame a la base) y GetClientValidationRules método GetClientValidationRules la GetClientValidationRules manera:

 public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { string errorMessage = String.Empty; if(String.IsNullOrWhiteSpace(ErrorMessage)) { // Check if they supplied an error message resource if(ErrorMessageResourceType != null && !String.IsNullOrWhiteSpace(ErrorMessageResourceName)) { var resMan = new ResourceManager(ErrorMessageResourceType.FullName, ErrorMessageResourceType.Assembly); errorMessage = resMan.GetString(ErrorMessageResourceName); } } else { errorMessage = ErrorMessage; } yield return new ModelClientValidationRule { ErrorMessage = errorMessage, ValidationType = "enforcetrue" }; } 

Sé que esta es una publicación anterior, pero quería compartir una forma simple de servidor para hacer esto. Usted crea una propiedad privada establecida en verdadero y compara su bool con esa propiedad. Si tu bool no está marcado (por defecto es falso) el formulario no se validará.

 public bool isTrue { get { return true; } } [Required] [Display(Name = "I agree to the terms and conditions")] [Compare("isTrue", ErrorMessage = "Please agree to Terms and Conditions")] public bool iAgree { get; set; } 

Probé varias soluciones, pero ninguna de ellas funcionó por completo para que obtuviera la validación del lado del cliente y del servidor. Entonces, ¿qué hice en mi aplicación MVC 5 para que funcione?

En su ViewModel (para la validación del lado del servidor):

 public bool IsTrue => true; [Required] [Display(Name = "I agree to the terms and conditions")] [Compare(nameof(IsTrue), ErrorMessage = "Please agree to Terms and Conditions")] public bool HasAcceptedTermsAndConditions { get; set; } 

En su página Razor (para la validación del lado del cliente):

 
@Html.CheckBoxFor(m => m.HasAcceptedTermsAndConditions) @Html.LabelFor(m => m.HasAcceptedTermsAndConditions) @Html.ValidationMessageFor(m => m.HasAcceptedTermsAndConditions) @Html.Hidden(nameof(Model.IsTrue), "true")

Me gustaría dirigir a las personas al siguiente Fiddle: https://dotnetfiddle.net/JbPh0X

El usuario agregó [Range(typeof(bool), "true", "true", ErrorMessage = "You gotta tick the box!")] su propiedad booleana, lo que hace que la validación del lado del servidor funcione.

Para que también funcione la validación del lado del cliente, agregaron el siguiente script:

 // extend jquery range validator to work for required checkboxes var defaultRangeValidator = $.validator.methods.range; $.validator.methods.range = function(value, element, param) { if(element.type === 'checkbox') { // if it's a checkbox return true if it is checked return element.checked; } else { // otherwise run the default validation function return defaultRangeValidator.call(this, value, element, param); } } 

Puede crear su propio atributo o usar CustomValidationAttribute .

Así es como usaría CustomValidationAttribute:

 [CustomValidation(typeof(BoolValidation), "ValidateBool")] 

donde BoolValidation se define como:

 public class BoolValidation { public static ValidationResult ValidateBool(bool boolToBeTrue) { if (boolToBeTrue) { return ValidationResult.Success; } else { return new ValidationResult( "Bool must be true."); } } 

Simplemente verifique si su representación de cadena es igual a True :

 [RegularExpression("True")] public bool TermsAndConditions { get; set; } 

[Required] atributo [Required] significa que requiere cualquier valor; puede ser verdadero o falso. Tendría que usar otra validación para eso.

¿Tiene los elementos adecuados configurados en el web.config ?

Eso podría causar que la validación no funcione.

También puede intentar crear un atributo de validación personalizado (ya que [Required] solo le importa si existe o no, y usted se preocupa por el valor):

 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] sealed public class RequiredTrueAttribute : ValidationAttribute { // Internal field to hold the mask value. readonly bool accepted; public bool Accepted { get { return accepted; } } public RequiredTrueAttribute(bool accepted) { this.accepted = accepted; } public override bool IsValid(object value) { bool isAccepted = (bool)value; return (isAccepted == true); } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, this.Accepted); } } 

Entonces, uso:

 [RequiredTrue(ErrorMessage="{0} requires acceptance to continue.")] public bool Agreement {get; set;} 

Desde aquí .

No sé de una manera a través de DataAnnotations, pero esto se hace fácilmente en su controlador.

 public ActionResult Add(Domain.Something model) { if (!model.MyCheckBox) ModelState.AddModelError("MyCheckBox", "You forgot to click accept"); if (ModelState.IsValid) { //'# do your stuff } } 

La única otra opción sería construir un validador personalizado para el lado del servidor y un validador remoto para el lado del cliente (la validación remota solo está disponible en MVC3 +)

Siguiendo con la publicación de ta.speot.is y el comentario de Jerad Rose:

La publicación dada no funcionará en el lado del cliente con una validación discreta. Esto debería funcionar en ambos campos:

 [RegularExpression("(True|true")] public bool TermsAndConditions { get; set; } 

Creo que la mejor manera de manejar esto es simplemente verificar en su controlador si la casilla es verdadera; de lo contrario, solo agregue un error a su modelo y haga que vuelva a mostrar su vista.

Como se indicó anteriormente, todo lo que [Required] hace es asegurarse de que haya un valor y en su caso, si no está marcado, sigue obteniendo el valor falso.

/// /// Resumen: -CheckBox para o la validación de verificación de tipo de entrada requerida no funciona la causa raíz y la solución de la siguiente manera /// /// Problema: /// La clave de este problema radica en la interpretación de la validación jQuery ‘ regla requerida ‘. Excavé un poco y encontré un código específico dentro de un archivo jquery.validate.unobtrusive.js: /// adapters.add (“required”, function (options) {/// if (options.element.tagName.toUpperCase () ! == “INPUT” || options.element.type.toUpperCase ()! == “CHECKBOX”) {/// setValidationValues ​​(opciones, “required”, true); ///} ///}); ///
/// Arreglo: (Corrección de script de Jquery al nivel de la página agregada al área requerida de checkbox) /// jQuery.validator.unobtrusive.adapters.add (“brequired”, function (options) {/// if (opciones.elemento) .tagName.toUpperCase () == “INPUT” && options.element.type.toUpperCase () == “CHECKBOX”) {/// options.rules [“required”] = true; /// if (options.message) ) {/// options.messages [“required”] = options.message; ///} /// Fix: (C # Code for MVC validation) /// Puedes ver que hereda de RequiredAttribute común. Además implementa IClientValidateable Esto es para asegurar que la regla se propague al lado del cliente (validación jQuery) también. ///
/// Ejemplo de anotación: /// [BooleanRequired] /// public bool iAgree {get; establecer ‘} ///

 public class BooleanRequired : RequiredAttribute, IClientValidatable { public BooleanRequired() { } public override bool IsValid(object value) { return value != null && (bool)value == true; } public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { return new ModelClientValidationRule[] { new ModelClientValidationRule() { ValidationType = "brequired", ErrorMessage = this.ErrorMessage } }; } } 

Mira la validación a prueba de tontos aquí . Puede descargarlo / instalarlo a través de Nuget.

Es una gran biblioteca pequeña para este tipo de cosas.

Esto es lo que funcionó para mí. Nada más lo hizo. Mvc 5:

Modelo

 public string True { get { return "true"; } } [Required] [Compare("True", ErrorMessage = "Please agree to the Acknowlegement")] public bool Acknowlegement { get; set; } 

Ver

  @Html.HiddenFor(m => m.True) @Html.EditorFor(model => model.Acknowlegement, new { htmlAttributes = Model.Attributes }) @Html.ValidationMessageFor(model => model.Acknowlegement, "", new { @class = "text-danger" }) 

enter image description here

enter image description here

Para ASP.NET Core MVC aquí está la validación de cliente y servidor, basada en la solución de dazbradbury

 public class EnforceTrueAttribute : ValidationAttribute, IClientModelValidator { 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; } public void AddValidation(ClientModelValidationContext context) { MergeAttribute(context.Attributes, "data-val", "true"); var errorMessage = ErrorMessage ?? $"The value for field {context.ModelMetadata.GetDisplayName()} must be true."; MergeAttribute(context.Attributes, "data-val-enforcetrue", errorMessage); } private void MergeAttribute(IDictionary attributes, string key, string value) { if (attributes.ContainsKey(key)) { return; } attributes.Add(key, value); } } 

Y luego en el cliente:

 $.validator.addMethod("enforcetrue", function (value, element, param) { return element.checked; }); $.validator.unobtrusive.adapters.addBool("enforcetrue"); 

Entonces el uso es:

 [EnforceTrue(ErrorMessage = "Please tick the checkbox")] public bool IsAccepted { get; set; }