4
votes

How do i set the min and max annotation on a Property, with Data Annotations Extensions?

This is what i have tried:

[Required(ErrorMessage = "Dette felt er påkrævet!")]
        [Digits(ErrorMessage = "Indtast kun cifre")]
        [Min(8, ErrorMessage = "Brugernavnet skal være 8 tegn langt.")]
        [Max(8, ErrorMessage = "Brugernavnet skal være 8 tegn langt.")]
        [Display(Name = "Brugernavn")]
        public string UserName { get; set; }

I get the following error:

Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: range

2

2 Answers

8
votes

Min and Max are for decimal types. For strings you use the [StringLength] or the [RegularExpression] attributes:

[StringLength(8, MinimumLength = 8)]
public string UserName { get; set; }
2
votes

I had the same problem as Kenci. I wanted to use the [Min] and [Max] at the same time so I could have a separate error message for each type of error, instead of a range. I too was confronted with...

Validation type names in unobtrusive client validation rules must be unique. The
following validation type was seen more than once: range

Because they decided to use the same validation name for both types!

I got around this by keeping the min, and creating my own Int Max.

Add this class somewhere, ideally in a CustomerValidation class

 public class MaximumDecimalCheck : ValidationAttribute, IClientValidatable
    {
        private readonly int _max;
        private readonly string _defaultErrorMessage = "";
        public MaximumDecimalCheck(int max, string defaultErrorMessage)
            : base(defaultErrorMessage)
        {
            _max = max;
            _defaultErrorMessage = defaultErrorMessage.Replace("{0}", _max.ToString());
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
                return null;

            int intValue;
            bool parsedDecimal = int.TryParse(value.ToString(), out intValue);
            if (parsedDecimal)
            {
                if (intValue < _max)
                {
                    return ValidationResult.Success;
                }
            }
            return new ValidationResult(_defaultErrorMessage);
        }

        public override string FormatErrorMessage(string name)
        {
            return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, _max);
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var modelClientValidationRule = new ModelClientValidationRule();
            modelClientValidationRule.ValidationType = "checkmaxint";
            modelClientValidationRule.ErrorMessage = _defaultErrorMessage;
            modelClientValidationRule.ValidationParameters.Add("maxint", _max.ToString());

            return new List<ModelClientValidationRule> { modelClientValidationRule };
        }
    }

Then, in your model object,

    [Required(ErrorMessage = "Monthly income (after tax) required")]
    [DataType(DataType.Currency)]
    [Display(Name = "Monthly income (after tax)")]
    [Min(200, ErrorMessage = "You do not earn enough")]
    [MaximumDecimalCheck(10000, "You earn to much a month")]
    public decimal? MonthlyIncomeAfterTax { get; set; }

the property type can be decimal, int etc... however it will only parse it as an int.

I failed to create a static type of a decimal so quickly gave in, if someone can answer that question i'd be very happy.

After adding the notation, reference the following javascript.

(function ($) {

    /*
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    */
    jQuery.validator.unobtrusive.adapters.add("checkmaxint", ['maxint'], function (options) {
        options.rules["checkmaxint"] = options.params;
        options.messages["checkmaxint"] = options.message;
    });

    jQuery.validator.addMethod("checkmaxint", function (value, element, params) {
        var maxValue = params.maxint;
        var inputValue = value;

        var parsedInt = parseInt(inputValue);
        if (isNaN(parsedInt)) {
            return false;
        }
        else if (parsedInt > maxValue) {
            return false;
        }
        else {
            return true;
        }
    });
    /*
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    */



} (jQuery));

I hope that helps.