validar mvc example asp.net-mvc validation checkbox data-annotations

example - ¿Cómo manejar Booleans/CheckBoxes en ASP.NET MVC 2 con DataAnnotaciones?



mvc 5 required checkbox (12)

Tengo un modelo de vista como este:

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; } }

El código de marcado de vista:

<%= Html.CheckBoxFor(m => m.AgreesWithTerms) %> <%= Html.LabelFor(m => m.AgreesWithTerms)%>

El resultado:

No se ejecuta la validación Está bien hasta ahora porque bool es un tipo de valor y nunca es nulo. Pero incluso si hago que AgreesWithTerms se pueda anular, no funcionará porque el compilador grita

"Las plantillas solo se pueden usar con acceso de campo, acceso a propiedades, índice de matriz de una dimensión o expresiones de indizador personalizadas de parámetro único".

Entonces, ¿cuál es la forma correcta de manejar esto?


"Requerido" es la validación incorrecta, aquí. Desea algo parecido a "Debe tener el valor verdadero", que no es lo mismo que "Obligatorio". ¿Qué pasa con el uso de algo como:

[RegularExpression("^true")]

?


¡La forma correcta de hacerlo es verificar el tipo!

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


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<ModelClientValidationRule> 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:

<script type="text/javascript"> jQuery.validator.addMethod("enforcetrue", function (value, element, param) { return element.checked; }); jQuery.validator.unobtrusive.adapters.addBool("enforcetrue"); </script>

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



Es suficiente agregar [RegularExpression]:

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

Nota: "Verdadero" debe comenzar con mayúscula T


Esto podría ser un "truco", pero puedes usar el atributo Rango incorporado:

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

El único problema es que la cadena de "advertencia" dirá "El FIELDNAME debe estar entre True y True".


Lo obtuve creando un atributo personalizado:

public class BooleanRequiredAttribute : RequiredAttribute { public override bool IsValid(object value) { return value != null && (bool) value; } }


Mi solución es este simple atributo personalizado para valores booleanos:

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

Entonces puedes usarlo así en tu modelo:

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


Mi solución es la siguiente (no es muy diferente a las respuestas ya presentadas, pero creo que se llama mejor):

/// <summary> /// Validation attribute that demands that a boolean value must be true. /// </summary> [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public class MustBeTrueAttribute : ValidationAttribute { public override bool IsValid(object value) { return value != null && value is bool && (bool)value; } }

Entonces puedes usarlo así en tu modelo:

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


Para las personas que tienen problemas para que esto funcione para la validación del lado del cliente (anteriormente yo): asegúrese de que también tiene

  1. Incluido <% Html.EnableClientValidation (); %> antes del formulario en la vista
  2. Se usó <% = Html.ValidationMessage o Html.ValidationMessageFor para el campo
  3. Creó un DataAnnotationsModelValidator que devuelve una regla con un tipo de validación personalizado
  4. Registrado la clase derivada de DataAnnotationsModelValidator en Global.Application_Start

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

es un buen tutorial para hacer esto, pero se pierde el paso 4.


Solo tomo lo mejor de las soluciones existentes y las reúno en una sola respuesta que permite la validación tanto del lado del servidor como del lado del cliente.

El aplicar al modelo de propiedades para asegurar un valor de bool debe ser verdadero:

/// <summary> /// Validation attribute that demands that a <see cref="bool"/> value must be true. /// </summary> /// <remarks>Thank you <c>http://.com/a/22511718</c></remarks> [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable { /// <summary> /// Initializes a new instance of the <see cref="MustBeTrueAttribute" /> class. /// </summary> public MustBeTrueAttribute() : base(() => "The field {0} must be checked.") { } /// <summary> /// Checks to see if the given object in <paramref name="value"/> is <c>true</c>. /// </summary> /// <param name="value">The value to check.</param> /// <returns><c>true</c> if the object is a <see cref="bool"/> and <c>true</c>; otherwise <c>false</c>.</returns> public override bool IsValid(object value) { return (value as bool?).GetValueOrDefault(); } /// <summary> /// Returns client validation rules for <see cref="bool"/> values that must be true. /// </summary> /// <param name="metadata">The model metadata.</param> /// <param name="context">The controller context.</param> /// <returns>The client validation rules for this validator.</returns> public IEnumerable<ModelClientValidationRule> 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", }; } }

El JavaScript para incluir para hacer uso de la validación discreta.

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


[Compare("Remember", ErrorMessage = "You must accept the terms and conditions")] public bool Remember { get; set; }