1

I'am stuck with some custom data validation in a .net mvc 5 project. I created custom ValidateAgeAttribute.cs with some custom data validation in it. And, I have a customvalidation.js file, where I added the method and adapter. Cannot make it work... not firing. Other validation (out from the box) are working properly with unobtrusive on the same form. It fails just on the custom one. Any help or suggestion are pretty welcome.

Thanks in advance.

 [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class ValidateAgeAttribute : ValidationAttribute, IClientValidatable
    {
        private const string DefaultErrorMessage = "Your age is invalid, your {0} should fall between {1} and {2}";

        public DateTime MinimumDateProperty { get; private set; }
        public DateTime MaximumDateProperty { get; private set; }

        public ValidateAgeAttribute(
            int minimumAgeProperty,
            int maximumAgeProperty)
            : base(DefaultErrorMessage)
        {
            MaximumDateProperty = DateTime.Now.AddYears(minimumAgeProperty * -1);
            MinimumDateProperty = DateTime.Now.AddYears(maximumAgeProperty * -1);
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            DateTime datevalue;
            if (value != null)
            {
                if (DateTime.TryParse(value.ToString(), out datevalue))
                {
                    if (value != null)
                    {
                        DateTime parsedValue = (DateTime)datevalue;

                        if (parsedValue <= MinimumDateProperty || parsedValue >= MaximumDateProperty)
                        {
                            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
                        }
                    }
                }

            }
            return ValidationResult.Success;
        }
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule()
            {
                ValidationType = "validateage",
                ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            };

            rule.ValidationParameters.Add("minumumdate", MinimumDateProperty.ToShortDateString());
            rule.ValidationParameters.Add("maximumdate", MaximumDateProperty.ToShortDateString());

            return new[] { rule };
        }

        public override string FormatErrorMessage(string name)
        {
            return string.Format(ErrorMessageString, name, MinimumDateProperty.ToShortDateString(), MaximumDateProperty.ToShortDateString());
        }
    }

the js :

$(document).ready(function () {
    $.validator.addMethod(
        'validateage',
        function (value, element, params) {
            return this.optional(element) || (dateConverter(value) >= dateConverter(params.minumumdate) && dateConverter(value) <= dateConverter(params.maximumdate));
        });

    $.validator.unobtrusive.adapters.add(
        'validateage', ['minumumdate', 'maximumdate'], function (options) {
            var params = {
                minumumdate: options.params.minumumdate,
                maximumdate: options.params.maximumdate
            };
            options.rules['validateage'] = params;
            options.messages['validateage'] = options.message;
        });
});

function dateConverter(value) {
    var valueParts = value.split("/");
    return new Date(+valueParts[2], valueParts[1] - 1, +valueParts[0]);
}

the script call order :

    <script src="~/Scripts/jquery.validate.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
    <script src="~/Scripts/shared/custom-validators.js"></script>

and the rendered view input :

<input class="form-control text-box single-line valid" data-val="true" data-val-validateage="Date de naissance incorrecte" data-val-validateage-maximumdate="07/01/2020" data-val-validateage-minumumdate="07/01/1925" id="Birthdate" name="Birthdate" type="text" value="" aria-describedby="Birthdate-error" aria-invalid="false">


hzl
  • 21
  • 3

1 Answers1

1

I found the issue. I called my helper action "revindvalidators" in the js related to the view, but it fired to soon, I placed it after the validators adds. And now it works.

$(document).ready(function () {
    // The validateage function
    $.validator.addMethod(
        'validateage',
        function (value, element, params) {
            return this.optional(element) || (dateConverter(value) >= dateConverter(params.minumumdate) && dateConverter(value) <= dateConverter(params.maximumdate));
        });

    $.validator.unobtrusive.adapters.add(
        'validateage', ['minumumdate', 'maximumdate'], function (options) {
            var params = {
                minumumdate: options.params.minumumdate,
                maximumdate: options.params.maximumdate
            };
            options.rules['validateage'] = params;
            options.messages['validateage'] = options.message;
    });

   helper.rebinvalidators();
});

function dateConverter(value) {
    var valueParts = value.split("/");
    return new Date(+valueParts[2], valueParts[1] - 1, +valueParts[0]);
}

rebindvalidators method in my helper file contains the following code :

   rebinvalidators: function() {
        var $form = $("#formId");
        $form.unbind();
        $form.data("validator", null);
        $.validator.unobtrusive.parse($form);
        $form.validate($form.data("unobtrusiveValidation").options);
    },
hzl
  • 21
  • 3