3

I'm trying to write a custom ValidationAttribute for a DateTime?

However, when it hits IsValid(object value) the value is already DateTime.Max

Nothing I can see in my code has set this value, but it means I am struggling to validate it.

The rule I want is "Null or After Today" - which means if there is a Null value then it's fine, but if there is a value then I want to validate.

public class AfterTodayAttribute : ValidationAttribute, IClientValidatable
{
    public AfterTodayAttribute()
    {
    }

    //Tried this as well...same result
    //protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    //{
    //    return base.IsValid(value, validationContext);
    //}

    public override bool IsValid(object value) 
    {
        //value is already a DateTime and set to DateTime.Max
        var valid = false; // for testing only
        return valid;
    }
}

...
[Display(Description = "Expiry Date")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
[AfterToday(false, ErrorMessage = "The Limit Expiry Date must be later than Today")]
public DateTime? NewExpiryDate { get; set; }
...
Peter Kiss
  • 9,309
  • 2
  • 23
  • 38
BlueChippy
  • 5,935
  • 16
  • 81
  • 131

2 Answers2

1

This should do the trick:

public override bool IsValid(object value)
{
    var dt = value as DateTime?;

    return dt == null || dt.Value.Date > DateTime.Today.AddDays(1).AddSeconds(-1);
}
Peter Kiss
  • 9,309
  • 2
  • 23
  • 38
  • That will ensure that dt is after today and not tomorrow 00:00. If you are not substracting the date then you should use this (greater or equal): dt.Value >= DateTime.Today.AddDays(1) – Peter Kiss Dec 09 '12 at 09:00
  • @PeterKiss but > operator will return true if even dt2 is one second later than dt1. – Behnam Esmaili Dec 09 '12 at 09:08
  • `dt = {31/12/9999 23:59:59}` and `dt==null`=`false` – BlueChippy Dec 09 '12 at 09:09
  • one thing I've thought of...I am using jQueryUI.datepicker to add a picker to my view. However, if I leave it empty and add a "Required" attribute then it correctly fails client-side validation. – BlueChippy Dec 09 '12 at 09:11
  • @BehnamEsmaili with the first approach (don't forget we first add one day to today!) that means you are at tomorrow which is valid. – Peter Kiss Dec 09 '12 at 09:14
  • @BlueChippy: sorry i don't understand what are you trid to say in your first comment. – Peter Kiss Dec 09 '12 at 09:15
  • when I get to the IsValid method, the value of `object value` is already set to a valid DateTime and NOT null? – BlueChippy Dec 09 '12 at 09:23
  • In the base case. What happens if someone says: validableObject.FutureDate = (DateTime?)null; There is a very low chance for this but why not? What happens if the model binder can not bind the value becose something changed? NullReferenceException is very ugly. – Peter Kiss Dec 09 '12 at 09:27
  • @PeterKiss: Confused - are you saying I should never allow null dates? I want the date to be either null or greater than today...either are valid for the application. – BlueChippy Dec 09 '12 at 09:43
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/20831/discussion-between-peter-kiss-and-bluechippy) – Peter Kiss Dec 09 '12 at 09:45
0

try this :

  public override bool IsValid(object value) 
    {           
        var dateValue = (DateTime ?) value;
        return dateValue.HasValue ? dateValue.Value > DateTime.Now : true;
    }
Behnam Esmaili
  • 5,835
  • 6
  • 32
  • 63
  • See comment above...`value` is NOT null when it hits this method, therefore it parses (correctly) to a DateTime (with DateTime.Max) as the value – BlueChippy Dec 09 '12 at 09:12
  • @BlueChippy you'r problem is with jquery UI datepicker default value.in fact datepicker always will post a value then you field never would be null. – Behnam Esmaili Dec 09 '12 at 09:13
  • try initializing you'r date field with DateTime.Now in case which the validation will return false as well. – Behnam Esmaili Dec 09 '12 at 09:15