Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a RangeAttribute for DateTime?

Tags:

c#

asp.net-mvc

I have a Datetime field in my Model and need to validate it so that when it is created it has to fall between Now and 6 Years Prior. I have tried using range like

[Range(DateTime.Now.AddYears(-6), DateTime.Now)]
public DateTime Datetim { get; set; }

But this throws an error cannot convert system datetime to double. Can anyone suggest a workaround to this in the model itself?

like image 464
Flood Gravemind Avatar asked Jun 26 '13 13:06

Flood Gravemind


3 Answers

Use this attribute:

public class CustomDateAttribute : RangeAttribute
{
  public CustomDateAttribute()
    : base(typeof(DateTime), 
            DateTime.Now.AddYears(-6).ToShortDateString(),
            DateTime.Now.ToShortDateString()) 
  { } 
}
like image 57
Ahmed KRAIEM Avatar answered Nov 15 '22 01:11

Ahmed KRAIEM


Even though there is an overload for Range attribute that accepts type and boundary values of that type and allows something like this:

[Range(typeof(DateTime), "1/1/2011", "1/1/2012", ErrorMessage="Date is out of Range")]

what you are trying to achieve is not possible using this attribute. The problem is that attributes accept only constants as parameters. Obviously neither DateTime.Now nor DateTime.Now.AddYears(-6) are constants.

However you can still do this creating your own validation attribute:

public class DateTimeRangeAttribute : ValidationAttribute
{
    //implementation
}
like image 45
Andrei Avatar answered Nov 15 '22 01:11

Andrei


jQuery validation does not work with RangeAttribute, per Rick Anderson. This renders the selected solution incorrect if you're using ASP.NET MVC 5's built-in jQuery validation.

Instead, see the below code from this answer.

public class WithinSixYearsAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        value = (DateTime)value;
        // This assumes inclusivity, i.e. exactly six years ago is okay
        if (DateTime.Now.AddYears(-6).CompareTo(value) <= 0 && DateTime.Now.CompareTo(value) >= 0)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult("Date must be within the last six years!");
        }
    }
}

And it's implemented like any other attribute.

[WithinSixYears]
public DateTime SixYearDate { get; set; }
like image 34
Sinjai Avatar answered Nov 15 '22 02:11

Sinjai