Codementor Events

MustComeBefore: make sure two dates are in the right order

Published Jan 23, 2020

Sometimes it is handy to know when people are working with time intervals, whether the dates are in the right chronological order. Of course, you perform this task with Javascript (when building a webpage). However, I think a more robust way of handling these errors is by using a datavalidation attribute.

Writing such an attribute might seem a daunting task at first, however, after having a look in the asp.net core source code, I was convinced this was easy, and here it is. Mind you, it is only for datetime fields, you might want to adapt for other things like integers.

[AttributeUsage(AttributeTargets.Property,AllowMultiple = false)]
    public class MustComeBeforeAttribute:ValidationAttribute
    {
       public string OtherProperty { get; private set; }

       public MustComeBeforeAttribute(string otherProperty) : base("Must match")
       {
           if (string.IsNullOrEmpty(otherProperty))
           {
               throw new ArgumentNullException("otherProperty");
           }

           this.OtherProperty = otherProperty;
       }

       public override bool RequiresValidationContext
       {
           get { return true; }
       }

       protected override ValidationResult IsValid(object value, ValidationContext validationContext)
       {
           PropertyInfo otherPropertyInfo = validationContext.ObjectType.GetProperty(this.OtherProperty);

           if (otherPropertyInfo == null)
           {
               return new ValidationResult($"Unknown property: {this.OtherProperty}");
           }

           try
           {
               DateTime otherPropertyValue =
                   (DateTime) otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
               if (otherPropertyValue == null)
               {
                    return new ValidationResult($"{this.OtherProperty} not of type DateTime");
               }

               var currentDateTime = (DateTime) value;
               if (currentDateTime <= otherPropertyValue)
               {
                   return ValidationResult.Success;
               }
               else
               {
                   return new ValidationResult("Dates are in reverse");
               }
           }
           catch (Exception e)
           {
               return new ValidationResult($"Exception: {e.Message}");
           }

       }

Easy right? Some improvements could be made though, like getting the errormessages from a resource (but I leave that excercise to the reader)

Discover and read more posts from Iede Snoek
get started