Jung
Jung

Reputation: 209

DataAnotation to validate a model, how do I validate it so that the date is not in the future?

I have the Review Model, I am trying to validate the model, so that when the user selects a date, it can't be the date in the future.

Review.cs

public class Review : BaseEntity{

    [Key]
    public int Id {get; set;}

    [Required(ErrorMessage="You need a restaurant name!")]
    public string RestaurantName {get; set;}

    [What do I put in here??]
    public DateTime Date {get; set;}


}

I am a newbie, and the documentation is kind of hard to understand.

Thank you so much for your help in advance.

Upvotes: 6

Views: 8696

Answers (3)

Try custom validation or standard model validation with attributes.

First option, set attribute on property standard dataannotations validation:

  • Set DateType attribute with errormessage properties and dateformatstring.
  • Set Range attribute if you want.
  • Set Display attribute for show label on screen.

    [DataType(DataType.Date), ErrorMessage = "Please enter a correct date format dd/mm/yyyy hh:mm", DisplayFormat( DataFormatString="{0:dd/MM/yyyy}", ApplyFormatInEditMode=true )]
    [Range(typeof(DateTime), "1/1/2016", "1/1/2011")]
    [Display(Name = "My Date")]
    public DateTime Date {get; set;}
    

Second option, Custom validation method:

You must extend the ValidationAttribute class and override IsValid:

public class MyDateValidation: ValidationAttribute
{
    public override bool IsValid(object value)
    {
        // check your business date property  
        DateTime myDatetime;
        bool isParsed = DateTime.TryParse((string)value, out myDatetime);
        if(!isParsed)
            return false;
        return true;
    }
}

[MyDateValidation(ErrorMessage="Your message")]
public Datetime myDate { get; set; }

See my other answer about this subject.

Upvotes: 4

Shyju
Shyju

Reputation: 218752

You can create a custom validation attribute which does your custom logic and use that to decorate your property name.

public class DateLessThanOrEqualToToday : ValidationAttribute
{
    public override string FormatErrorMessage(string name)
    {
        return "Date value should not be a future date";
    }

    protected override ValidationResult IsValid(object objValue,
                                                   ValidationContext validationContext)
    {
        var dateValue = objValue as DateTime? ?? new DateTime();

        //alter this as needed. I am doing the date comparison if the value is not null

        if (dateValue.Date > DateTime.Now.Date)
        {
           return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
        return ValidationResult.Success;
    }
}

Now in your view model, decorate your property name with this new custom attribute

[DateLessThanOrEqualToToday]
public DateTime Date { get; set; }

This custom validation attribute is primarly focusing on your specific validation logic. You can alter it to include more null checks, minimum value check etc as needed.

Upvotes: 8

Vlatko Vlahek
Vlatko Vlahek

Reputation: 1889

You need to write a custom validator for this. You can name it as you wish, for example.

[DateNotInTheFuture]
public DateTime Date { get; set; }

Process itself is explained in good detail in this article: https://msdn.microsoft.com/en-us/library/cc668224.aspx

Summarised:

  • Create new sealed public class that inherits ValidationAttribute
  • Inside that class implement an override for IsValid method.
  • Write your custom validation logic inside IsValid method and return the result

Upvotes: 1

Related Questions