10

I want to check an Datetime field in a form. The field is valid between 01/10/2008 and 01/12/2008. Here is how I defined the viewmodel property:

    [Required(ErrorMessage = "The date value is mandatory")]
    [DataType(DataType.DateTime)]
    [Range(typeof(DateTime), "01/10/2008", "01/12/2008")]
    [DisplayName("When the work starts")]
    public DateTime StartWork { get; set; }

I want to validate this on the client side. But I get always an error. I give the value 01/11/2008 and it tells me, that the date must be defined between 01/10/2008 and 01/12/2008. I read that it doesn't work client validation without jquery, isn't it? Or I forgot anything? What alternatives are there to get any solution of that problem.

MrScf
  • 2,407
  • 5
  • 27
  • 40

5 Answers5

14

I think you can implement this using custom validation in MVC. Try using this:

[ValidateDateRange]
public DateTime StartWork { get; set; }

Here is your custom validation implementation:

namespace MVCApplication
    {   

        public class ValidateDateRange: ValidationAttribute
        {
            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
            {                 
               // your validation logic
                if (value >= Convert.ToDateTime("01/10/2008") && value <= Convert.ToDateTime("01/12/2008") )
                {
                    return ValidationResult.Success;
                }
                else
                {
                    return new ValidationResult("Date is not in given range.");
                }
            }
        }
    }

UPDATE:

You can also pass date ranges as parameters to make the validation a generic one:

[ValidateDateRange(FirstDate = Convert.ToDateTime("01/10/2008"), SecondDate = Convert.ToDateTime("01/12/2008"))]
public DateTime StartWork { get; set; }

Custom Validation:

    namespace MVCApplication
        {   

            public class ValidateDateRange: ValidationAttribute
            {
              public DateTime FirstDate { get; set; }
              public DateTime SecondDate { get; set; }

                protected override ValidationResult IsValid(object value, ValidationContext validationContext)
                {                 
                    // your validation logic
                    if (value >= FirstDate && value <= SecondDate)
                    {
                        return ValidationResult.Success;
                    }
                    else
                    {
                        return new ValidationResult("Date is not in given range.");
                    }
                }
            }
        }

UPDATE 2: (For Client Side) A very simple jQuery logic should do the client validation. Check below:

$(document).ready(function(){

  $("#btnSubmit").click(function(){

    var dt = $("#StartWork").val();

    var d = new Date(dt);
    var firstDate = new Date("2008-01-10");
    var secondDate = new Date("2008-01-12");

    if(d>= firstDate && d<= secondDate)
    {
      alert("Success");
    }
    else
    {
      alert("Date is not in given range.");
    }

  });

});

Please check this JSFiddle to see the working demo:Date Range Validation

Saket Kumar
  • 4,363
  • 4
  • 32
  • 55
  • 1
    This is the route I would take, but I would also add the date range to validate as a paramater so the code can be reused for all different types of date ranges – JensB Nov 28 '14 at 08:19
  • Thanks, I will try this suggestion! – MrScf Nov 28 '14 at 08:23
  • But your custom validation only work on server side validation, client side validation need put matching ValidationType to Javascript. If the ValidationType is custom not found in Javascript, have to add on new javascript function to the java script file. Keep in mine if you have more than one custom validation using regular expression as ValidationType, then you can not validate them on the same time. One web control only allow one regular expression validation. – Harris Yer Nov 28 '14 at 09:57
  • To validating on client side, ValidateDateRangeAttribute should only implement IClientValidatable interface, isn't it? On client side I should create an adapter to add a new rule. Would that work? – MrScf Nov 28 '14 at 10:37
  • You can try, but i always prefer to use jQuery for client side validation. – Saket Kumar Nov 28 '14 at 11:33
  • Hi saket, the solution is nice but it doesn't validate on client side – MrScf Nov 28 '14 at 22:39
  • @Ziggy: Updated the client side validation. Check it from your end. – Saket Kumar Nov 29 '14 at 12:10
  • For the server-side validation - can you explain why this had to be custom? Why does `[Range(typeof(DateTime), "01/10/2008", "01/12/2008")]` not work or foot the bill, or is there some other variant that is built-in that could have worked? Is doing it this custom way the only way to do it? I just would have enjoyed more backstory than simply having the solution. – vapcguy Mar 25 '15 at 21:51
  • Actually, I found this: "Note: jQuery validation does not work with the Range attribute and DateTime." http://www.asp.net/mvc/overview/getting-started/introduction/adding-validation – vapcguy Mar 26 '15 at 00:43
  • I don't think Range annotation take DateTime as input. You can see its input types here: https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.rangeattribute(v=vs.110).aspx – Saket Kumar Apr 09 '15 at 11:16
  • Why did you mark this answer as correct if he didn't answer your question? You had a good question an all he did was distract and offer server side and garbage client side code (using alerts instead of a validation library). Did you ever get this question answered? – Rabbi Aug 12 '16 at 21:42
3

You must specify dates in a certain format on the attribute and you also much provide the value in that format as well. The date input doesn't like MM/dd/yyyy, even though that's the format it displays in! Pretty retarded IMHO.

You need to add min and max like so:

Resulting Html

<input class="form-control text-box single-line input-validation-error" data-val="true" data-val-date="The field DOB must be a date." data-val-required="The DOB field is required." id="DOB" name="DOB" type="date" value="1932-01-01" aria-required="true" aria-describedby="DOB-error" aria-invalid="true" min="1932-01-01" max="2015-01-01">

Model

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
public DateTime DOB { get; set; }

View

@Html.EditorFor(model => model.DOB, new { htmlAttributes = new { @class = "form-control", min = "1900-01-01", max = "2015-01-01" } })

Then you will get min or max errors in the UI:

enter image description here

toddmo
  • 20,682
  • 14
  • 97
  • 107
2

Though portions of this have been posted before and downvoted as not working. I can confirm this does work as long as you have both the range and the format string specified.

[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:mm-dd-yyyy}", ApplyFormatInEditMode = true)]
[Range(typeof(DateTime), "1/1/1900", "12/31/2018",
    ErrorMessage = "Value for {0} must be between {1} and {2}")]
[Display(Name = "Date of Birth")]
public DateTime DateOfBirth { get; set; }
Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73
0

Checking the range date can also be done using FluentValidation, that can be another solution to your problem, check my answer her. Hope this helps

MVC model validation for date

Community
  • 1
  • 1
Zinov
  • 3,817
  • 5
  • 36
  • 70
-3

Use DataFormat attribute for specifying the date format explicitly as,

[DisplayFormat(DataFormatString="{0:C}")]

Refer MSDN doc

Venkatesh
  • 1,204
  • 1
  • 10
  • 18
  • Would it help that with the validation on client side? – MrScf Nov 28 '14 at 06:31
  • I found this linkhttp://stackoverflow.com/questions/21777412/mvc-model-validation-for-date . It seems,jquery doesn't work with ranges – MrScf Nov 28 '14 at 06:50