126

Validation using attributes in asp.net mvc is really nice. I have been using the [Range(min, max)] validator this far for checking values, like e.g.:

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

However - now I need to check the min and max condition separately. I expected to find attributes like these:

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

Are there any predefined attributes for writing this? Or how do I achieve this?

1

4 Answers 4

231

I don't think min/max validations attribute exist. I would use something like

[Range(1, Int32.MaxValue)]

for minimum value 1 and

[Range(Int32.MinValue, 10)]

for maximum value 10

Sign up to request clarification or add additional context in comments.

7 Comments

It is a bit hacky.. but sometimes hacks make me feel more comfortable :)
Went with this, but had problems once we were dealing with huge floating point values.
This approach is fine as long as you override the default error message or you will get something horrible like: "Property x must be between -2e^31-1 and 10".
The default message would display as "The field {field_name} must be between 1 and 2147483647.". I've edited the answer to add custom error messages which you can set to something more sensible.
RangeAttribute has AllowMultiple = false, so this cannot compile.
|
60

Here is how I would write a validator for 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;
        }
    }

The MinValue Attribute should be fairly the same

6 Comments

Ok, was expecting that they exist, but fair enough to write them. Thx!
Just FYI this would not magically validate the form on the Javascript end. You would need to write additional code + js for that.
@basarat actually you won't need extra JS, the jquery validation library already has functions for min/max, you just need to implement the IClientValidation interface on the above attribute and return the correct values from the GetClientValidationRules method
@WickyNilliams would you add an answer with an example of your comment, or CharlesOuellet will you edit this answer with an example of Wicky's comment? I would love to upvote a working example that includes client side validation.
@JohnieKarr I don't work with .NET anymore, so I can't provide much of an answer. That said, this answer below seems to show exactly what I described
|
41

A complete example of how this could be done. To avoid having to write client-side validation scripts, the existing ValidationType = "range" has been used.

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

}

1 Comment

Great answer. I would modify the error message a bit: "Enter a value greater than or equal to " is a more (grammatically-speaking) correct error message.
0

jQuery Validation Plugin already implements min and max rules, we just need to create an adapter for our custom attribute:

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

Adapter:

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

Min attribute would be very similar.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.