Validadores de valor mínimo / máximo en asp.net mvc

106

La validación usando atributos en asp.net mvc es realmente agradable. He estado usando el [Range(min, max)]validador hasta ahora para verificar valores, como por ejemplo:

[Range(1, 10)]
public int SomeNumber { get; set; }

Sin embargo, ahora necesito verificar la condición mínima y máxima por separado. Esperaba encontrar atributos como estos:

[MinValue(1, "Value must be at least 1")]
[MaxValue(10, "Value can't be more than 10")]
public int SomeNumber { get; set; }

¿Hay atributos predefinidos para escribir esto? ¿O cómo lo logro?

stiank81
fuente
FluentValidation puede ser otra solución para resolver el rango de fechas. Aquí está mi respuesta a otra pregunta que podría ser útil .
Zinov

Respuestas:

48

Así es como escribiría un validador para MaxValue

public class MaxValueAttribute : ValidationAttribute
    {
        private readonly int _maxValue;

        public MaxValueAttribute(int maxValue)
        {
            _maxValue = maxValue;
        }

        public override bool IsValid(object value)
        {
            return (int) value <= _maxValue;
        }
    }

El atributo MinValue debería ser bastante el mismo

Charles Ouellet
fuente
Ok, esperaba que existieran, pero lo suficientemente justo como para escribirlos. ¡Gracias!
stiank81
1
Para su información, esto no validaría mágicamente el formulario en el extremo de Javascript. Necesitaría escribir código adicional + js para eso.
basarat
3
@basarat en realidad no necesitará JS adicional, la biblioteca de validación jquery ya tiene funciones para min / max, solo necesita implementar la IClientValidationinterfaz en el atributo anterior y devolver los valores correctos del GetClientValidationRulesmétodo
WickyNilliams
@WickyNilliams, ¿agregaría una respuesta con un ejemplo de su comentario, o CharlesOuellet, editaría esta respuesta con un ejemplo del comentario de Wicky? Me encantaría votar a favor de un ejemplo funcional que incluya la validación del lado del cliente.
Johnie Karr
@JohnieKarr Ya no trabajo con .NET, así que no puedo dar mucha respuesta. Dicho esto, esta respuesta a continuación parece mostrar exactamente lo que describí
WickyNilliams
195

No creo que exista el atributo de validaciones mínimas / máximas. Usaría algo como

[Range(1, Int32.MaxValue)]

para valor mínimo 1 y

[Range(Int32.MinValue, 10)]

para valor máximo 10

Chico
fuente
4
Mmm .. No estoy muy cómodo con esto. Me parece un poco hacky.
stiank81
21
Es un poco hacky ... pero a veces los trucos me hacen sentir más cómodo :)
Guy
4
Este enfoque está bien siempre que anule el mensaje de error predeterminado o obtendrá algo horrible como: "La propiedad x debe estar entre -2e ^ 31-1 y 10".
Nine Tails
2
¿Cómo es esto hacky e incómodo? Me parece un buen enfoque.
1
RangeAttributetiene AllowMultiple = false, por lo que no se puede compilar.
Daniel Schilling
38

Un ejemplo completo de cómo se podría hacer esto. Para evitar tener que escribir scripts de validación del lado del cliente, se ha utilizado el ValidationType = "range" existente.

public class MinValueAttribute : ValidationAttribute, IClientValidatable
{
    private readonly double _minValue;

    public MinValueAttribute(double minValue)
    {
        _minValue = minValue;
        ErrorMessage = "Enter a value greater than or equal to " + _minValue;  
    }

    public MinValueAttribute(int minValue)
    {
        _minValue = minValue;
        ErrorMessage = "Enter a value greater than or equal to " + _minValue;
    }

    public override bool IsValid(object value)
    {
        return Convert.ToDouble(value) >= _minValue;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule();
        rule.ErrorMessage = ErrorMessage;
        rule.ValidationParameters.Add("min", _minValue);
        rule.ValidationParameters.Add("max", Double.MaxValue);
        rule.ValidationType = "range";
        yield return rule;
    }

}
Mario
fuente
8
Gran respuesta. Modificaría un poco el mensaje de error: "Ingrese un valor mayor o igual que" es un mensaje de error más correcto (gramaticalmente hablando).
Tieson T.Julio
0

El complemento de validación jQuery ya implementa reglas mínimas y máximas, solo necesitamos crear un adaptador para nuestro atributo personalizado:

public class MaxAttribute : ValidationAttribute, IClientValidatable
{
    private readonly int maxValue;

    public MaxAttribute(int maxValue)
    {
        this.maxValue = maxValue;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule();

        rule.ErrorMessage = ErrorMessageString, maxValue;

        rule.ValidationType = "max";
        rule.ValidationParameters.Add("max", maxValue);
        yield return rule;
    }

    public override bool IsValid(object value)
    {
        return (int)value <= maxValue;
    }
}

Adaptador:

$.validator.unobtrusive.adapters.add(
   'max',
   ['max'],
   function (options) {
       options.rules['max'] = parseInt(options.params['max'], 10);
       options.messages['max'] = options.message;
   });

El atributo Min sería muy similar.

Benas Radzevicius
fuente