SantasNotReal
SantasNotReal

Reputation: 1281

Validate that an entered date is older than today's date

I've got an Html.TextBoxFor element where a user can enter their birthdate. I want to make sure they only enter a date that is older than today's date. Here is the validation I have in my model:

[Required(ErrorMessage = "Birthdate is required")]
[RegularExpression(@"^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$", ErrorMessage = "Please use MM/DD/YYYY")]
[DataType(DataType.Date)]
public System.DateTime Dob { get; set; }

and here is the relevant part of my view:

<td>
  @Html.Label("DOB:")
  @Html.TextBoxFor(m => m.Driver.Dob, "{0:dd/MM/yyyy}")
  @Html.ValidationMessageFor(m => m.Driver.Dob)
</td>

Is there a built-in way offered by .net to do this?

Upvotes: 1

Views: 3544

Answers (3)

AthibaN
AthibaN

Reputation: 2087

If you're ok with using JQuery DatePicker, follow this link, change

@Html.TextBox("",  String.Format("{0:yyyy-MM-dd}", Model.HasValue ? Model : DateTime.Today), new { @class = "dp", @readonly = "readonly"})

<script type='text/javascript'>

$(document).ready(function () {   
            $(".dp").datepicker({
                maxDate: new Date,
                dateFormat: 'dd/M/yy',
                changeYear: true,
                changeMonth: true
            });
});

</script>

Upvotes: 0

Patryk Ćwiek
Patryk Ćwiek

Reputation: 14318

You could try to use IValidatableObject...

So then:

public class MyViewModel : IValidatableObject
{
    [Required(ErrorMessage = "Birthdate is required")]
    [DataType(DataType.Date)]
    public System.DateTime Dob { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if(Dob >= DateTime.Today)
            yield return new ValidationResult("Dob date should be set in the past", new [] { "Dob" });
    }
}

Then just calling ModelState.IsValid in the controller worked just fine for me so far, but if you experience any problems with it, there are other answers that tackle that problem

Admittedly, in such a simple case it might be better and easier to create your own attribute per Jeroen's answer, but if you need any further and/or more complicated logic that may even involve other class members, then IValidatableObject is the built-in way to go.

Upvotes: 2

Jeroen Vannevel
Jeroen Vannevel

Reputation: 44439

Create your own custom attribute.

[DateValidation]
public System.DateTime Dob { get; set; }

public class DateValidationAttribute : ValidationAttribute {
  public override bool IsValid(object value) {
     DateTime dateValue;
     var date = DateTime.TryParse(value.toString(), out dateValue);
     // "var dateValue = (DateTime) value;" might work as well, let me know what does.
     return dateValue < DateTime.Now;
  }
}

Important: the name of the attribute class should end with Attribute.

Upvotes: 2

Related Questions