0

I have a datetime field in my model which should be validated:

[DateValidation(ErrorMessage = "AccDate should be greater or equal to the current date")]
public DateTime? AccDate { get; set; }

DateValidation is a hand made class:

public class DateValidation : ValidationAttribute, IClientValidatable
{
    public DateValidation()
    {

    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (validationContext.ObjectInstance is OrderModel)
        {
            var model = validationContext.ObjectInstance as OrderModel;

            if (model.EndDate == null && model.AccDate.HasValue)
            {
                if (model.RecDate.HasValue && model.AccDate.Value < model.RecDate.Value)
                {
                    var errorMessage = "AccDate should be greater than the RecDate";
                    return new ValidationResult(errorMessage);
                }

                if (model.AccDate.Value < DateTime.Now)
                {
                    var errorMessage = "AccDate should be greater or equal to the current date";
                    return new ValidationResult(errorMessage);
                }
            }
        }

        return ValidationResult.Success;
    }

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

And also I have a datevalidator.js file:

$.validator.unobtrusive.adapters.add("datevalidator", [], function (values) {
    values.rules['datevalidator'] = {
    };
    values.messages['datevalidator'] = values.message;
});

$.validator.addMethod("datevalidator", function (value, element, params) {
    if (element.id == "AccDate") {    
        if (value) {
            var nowDate = new Date($.now());
            var accDate = new Date(value);
            var recDate = new Date($("#RecDate").val());

            if (accDate <= recDate) {
                return false;
            }

            if (accDate < nowDate) {
                return false;
            }

            return true;
        }
    }   
});

By itself everything is working. Validation prevent me from doing unaceptable action BUT, I have an issue.

My error message which I receive is always equal to: "AccDate should be greater or equal to the current date"

As I understand, it happend because of [DateValidation(ErrorMessage = "AccDate should be greater or equal to the current date")] and rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());. And so far I cant change it.

When the page is loaded, I am getting data-val-datevalidator attribute for $("#AccDate") which contains this error message. I tried to change it and make it different for each situation (similar to what ValidationResult are returning):

if (accDate <= recDate) {
    $("#AccDate").attr("data-val-datevalidator", "AccDate should be greater than the RecDate");
    return false;
}

But there were no reaction at all (attribute value has changed but showed error message is still old one).

How can I change my error message for different one in datevalidator.js?

Olegs Jasjko
  • 2,128
  • 6
  • 27
  • 47
  • `var errorMessage = "AccDate should be greater than the RecDate";` Just change that string? – Praxis Ashelin Mar 25 '15 at 10:32
  • The jquery.validate.unobtrusive reads the value of the `data-val-datevalidator` attribute when the page is first parsed so you don't have much control over this unless you reparse the validator each time. –  Mar 25 '15 at 10:57
  • ...Then how can I reparse it? – Olegs Jasjko Mar 25 '15 at 11:04
  • @OlegsJasjko, [Example here](http://stackoverflow.com/questions/26542509/validate-dynamically-added-fields/26542591#26542591), but this is not the correct approach. You should have 2 validation attributes (say) `[DateGreaterThatToday]` (to compare with the current date) and `[DateGreaterThan("RecDate")]` (to compare with another property) –  Mar 25 '15 at 11:30
  • The problem is that means to create another validation for each special situation. Not good at all. – Olegs Jasjko Mar 25 '15 at 11:34
  • Why would you need to create others (what other 'special' conditions do you have)? In any case you current implementation only allows you to compare against one property named `RecDate` which is far more inflexible than my suggestion which allows you to compare against any other `DateTime` property. In fact is so inflexible, you may as well just check the value in the controller when you post back. –  Mar 25 '15 at 11:39
  • In perspective I will need to validate date not only by greater on not, but also only in specific situations (for examole, order status or stage). This is example when I will need new validation. – Olegs Jasjko Mar 25 '15 at 11:51
  • I suggest you do some research and examine some examples of validation attributes and client side validation. And if you want validation based on the value of other properties then you use a `RequiredIf` type attribute or variant (for example [foolproof](http://foolproof.codeplex.com/). –  Mar 25 '15 at 12:02

0 Answers0