Cory Ander wanted to make sure his users enter a date value that is reasonably close to the current date. He's writing an MVC 3 app and envisioned using a validation attribute like the following.
public class TransactionDispute { [RecentDate] public DateTime TransactionDate { get; set; } // ... }
Corey came up with the following.
public class RecentDateAttribute : ValidationAttribute { public RecentDateAttribute() :base("{0} must be recent") { MinimumDate = DateTime.Now.AddDays(-1); } protected DateTime MinimumDate { get; set; } protected override ValidationResult IsValid( object value, ValidationContext validationContext) { var date = (DateTime) value; if (date < MinimumDate) { return new ValidationResult( FormatErrorMessage(validationContext.DisplayName) ); } return ValidationResult.Success; } }
It seems to work - what could possibly be wrong?
Comments
Otherwise, you're using "DateTime.Now" which will always be something like 2/21/2011 10:45AM. Subtract a day and you'll be at 10:45AM yesterday. Since the date field will be just days only, you'll have 2/20/2011 12:00:00 AM which is not less than 2/20/2011 10:45:00 AM. They probably want to use DateTime.Today (midnight) and a less than or equal to for the comparison.
I'd also add that usually people insert dates with time being 00:00, so actually if it's a day before you wont let people insert dates, because you're using DateTime.Now.
Using DateTime.Today is better for this, IMO.
either DateTime.TryParse() or value as DateTime would prevent an exception. return false if the value is null or not a date.
Personally, I think the sneakiest problem is initializing the compare date in the constructor....
-Minimum date is set in the constructor, which a future developer could overlook.
-No argument validation on "value" which would result in a NullReferenceException the first time it is referenced.
-Direct casting of (DateTime) will result in FormatException (I believe) if "value" is not a date.
-No argument validation on "validationContext" which would result in a NullReferenceException on the FormarErrorMessage(... line.