Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Greater Than or Equal To Today Date validation annotation in MVC3

Has anyone seen an MVC3 data annotation for Date validation that requires a single selected date to be equal to or greater than current date?

If there's already a third party add on that's cool too. I'm already using the DataAnnotationsExtensions but it doesn't offer what I'm looking for.

There doesn't seem to be any reference of this on. So, hoping someone has already solved this before I try to reinvent the wheel and write my own custom validator.

I've tried Range but that requires 2 dates and both have to be constants in string format such as [Range(typeof(DateTime), "1/1/2011", "1/1/2016")] but that doesn't help. And the DataAnnotationsExtensions Min validator only accepts int and double


Update Solved

Thanks to @BuildStarted this is what I ended up with and it works great server-side and now client side with my script


using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace Web.Models.Validation {

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public sealed class DateMustBeEqualOrGreaterThanCurrentDateValidation : ValidationAttribute, IClientValidatable {

        private const string DefaultErrorMessage = "Date selected {0} must be on or after today";

        public DateMustBeEqualOrGreaterThanCurrentDateValidation()
            : base(DefaultErrorMessage) {
        }

        public override string FormatErrorMessage(string name) {
            return string.Format(DefaultErrorMessage, name);
        }  

        protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
            var dateEntered = (DateTime)value;
            if (dateEntered < DateTime.Today) {
                var message = FormatErrorMessage(dateEntered.ToShortDateString());
                return new ValidationResult(message);
            }
            return null;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
            var rule = new ModelClientCustomDateValidationRule(FormatErrorMessage(metadata.DisplayName));
            yield return rule;
       }
    }

    public sealed class ModelClientCustomDateValidationRule : ModelClientValidationRule {

        public ModelClientCustomDateValidationRule(string errorMessage) {
            ErrorMessage = errorMessage;
            ValidationType = "datemustbeequalorgreaterthancurrentdate";
        }
    }
}

And in my model

[Required]
[DateMustBeEqualOrGreaterThanCurrentDate]
public DateTime SomeDate { get; set; }

The client side script

/// <reference path="jquery-1.7.2.js" />

jQuery.validator.addMethod("datemustbeequalorgreaterthancurrentdate", function (value, element, param) {
    var someDate = $("#SomeDate").val();
    var today;
    var currentDate = new Date();
    var year = currentDate.getYear();
    var month = currentDate.getMonth() + 1;  // added +1 because javascript counts month from 0
    var day = currentDate.getDate();
    var hours = currentDate.getHours();
    var minutes = currentDate.getMinutes();
    var seconds = currentDate.getSeconds();

    today = month + '/' + day + '/' + year + '  ' + hours + '.' + minutes + '.' + seconds;

    if (someDate < today) {
        return false;
    }
    return true;
});

jQuery.validator.unobtrusive.adapters.addBool("datemustbeequalorgreaterthancurrentdate");
like image 673
CD Smith Avatar asked Jun 04 '12 20:06

CD Smith


2 Answers

Create a custom attribute.

public class CheckDateRangeAttribute: ValidationAttribute {
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
        DateTime dt = (DateTime)value;
        if (dt >= DateTime.UtcNow) {
            return ValidationResult.Success;
        }

        return new ValidationResult(ErrorMessage ?? "Make sure your date is >= than today");
    }

}

code was written off the cuff so fix any errors :)

like image 126
Buildstarted Avatar answered Nov 12 '22 13:11

Buildstarted


Use [Remote] for special validations, simple and easy:

Your model:

[Remote("ValidateDateEqualOrGreater", HttpMethod="Post", 
    ErrorMessage = "Date isn't equal or greater than current date.")]
public DateTime Date { get; set; }
//other properties

Your action:

[HttpPost]
public ActionResult ValidateDateEqualOrGreater(DateTime Date)
{
     // validate your date here and return True if validated
     if(Date >= DateTime.Now)
     {
       return Json(true);
     }
     return Json(false);    
}
like image 35
Matija Grcic Avatar answered Nov 12 '22 12:11

Matija Grcic