validar regulares que mvc isvalid formulario expresiones electronico correo campos asp.net asp.net-mvc validation asp.net-mvc-2 data-annotations

asp.net - regulares - Anotaciones de datos para la validación, ¿al menos un campo obligatorio?



validar campos formulario mvc (4)

Si tengo un objeto de búsqueda con una lista de campos, ¿puedo, mediante el espacio de nombres System.ComponentModel.DataAnnotations, configurarlo para validar que al menos uno de los campos en la búsqueda no es nulo o está vacío? es decir, todos los campos son opcionales, pero al menos uno siempre debe ingresarse.


Creé un validador personalizado para esto, no le dará validación del lado del cliente, solo del lado del servidor.

Tenga en cuenta que para que esto funcione, deberá usar tipos que nullable valores nullable , ya que los tipos de valores tendrán como valor predeterminado 0 o false .

Primero crea un nuevo validador:

using System.ComponentModel.DataAnnotations; using System.Reflection; // This is a class-level attribute, doesn''t make sense at the property level [AttributeUsage(AttributeTargets.Class)] public class AtLeastOnePropertyAttribute : ValidationAttribute { // Have to override IsValid public override bool IsValid(object value) { // Need to use reflection to get properties of "value"... var typeInfo = value.GetType(); var propertyInfo = typeInfo.GetProperties(); foreach (var property in propertyInfo) { if (null != property.GetValue(value, null)) { // We''ve found a property with a value return true; } } // All properties were null. return false; } }

A continuación, puede decorar sus modelos con esto:

[AtLeastOneProperty(ErrorMessage="You must supply at least one value")] public class SimpleTest { public string StringProp { get; set; } public int? Id { get; set; } public bool? BoolProp { get; set; } }

Luego, cuando llame a ModelState.IsValid se llamará a su validador y su mensaje se agregará a ValidationSummary en su vista.

Tenga en cuenta que puede extender esto para verificar el tipo de propiedad que regresa, o buscar atributos en ellos para incluir / excluir de la validación si lo desea, esto es asumiendo un validador genérico que no sabe nada sobre el tipo que está validando .



He extendido la respuesta de Zhaph para admitir la agrupación de propiedades.

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class AtLeastOnePropertyAttribute : ValidationAttribute { private string[] PropertyList { get; set; } public AtLeastOnePropertyAttribute(params string[] propertyList) { this.PropertyList = propertyList; } //See http://.com/a/1365669 public override object TypeId { get { return this; } } public override bool IsValid(object value) { PropertyInfo propertyInfo; foreach (string propertyName in PropertyList) { propertyInfo = value.GetType().GetProperty(propertyName); if (propertyInfo != null && propertyInfo.GetValue(value, null) != null) { return true; } } return false; } }

Uso:

[AtLeastOneProperty("StringProp", "Id", "BoolProp", ErrorMessage="You must supply at least one value")] public class SimpleTest { public string StringProp { get; set; } public int? Id { get; set; } public bool? BoolProp { get; set; } }

Y si quieres tener 2 grupos (o más):

[AtLeastOneProperty("StringProp", "Id", ErrorMessage="You must supply at least one value")] [AtLeastOneProperty("BoolProp", "BoolPropNew", ErrorMessage="You must supply at least one value")] public class SimpleTest { public string StringProp { get; set; } public int? Id { get; set; } public bool? BoolProp { get; set; } public bool? BoolPropNew { get; set; } }


Esta pregunta es bastante antigua, pero a partir de .NET 3.5 (creo), IValidatableObject puede ayudar con situaciones difíciles de validación. Puede implementarlo para validar reglas comerciales arbitrarias. En este caso, algo así como:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (string.IsNullOrWhiteSpace(FieldOne) && string.IsNullOrWhiteSpace(FieldTwo)) yield return new ValidationResult("Must provide value for either FieldOne or FieldTwo.", new string[] { "FieldOne", "FieldTwo" }); }