2

I have a RangeAttribute that checks if the value of a data field is within a specified range of values here, that gives me a validation error even if I pick a date in between "01/01/2000", "01/01/2015":

 [Range(typeof(DateTime), "01/01/2000", "01/01/2015")]
 [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
 [DataType(DataType.Date)]
 public Nullable<System.DateTime> Date { get; set; }

Here is my edit.cshtml code:

@model StringLength.Models.Employee

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

<fieldset>
    <legend>Employee</legend>

    @Html.HiddenFor(model => model.ID)

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Gender)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Gender)
        @Html.ValidationMessageFor(model => model.Gender)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Email)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Email)
        @Html.ValidationMessageFor(model => model.Email)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Age)
        @Html.ValidationMessageFor(model => model.Age)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Date)
        @Html.ValidationMessageFor(model => model.Date)
    </div>

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

For instance, if I pick 1.1.2014, I am NOT supposed to see any validation error. Could anyone please help? Thanks in advance! enter image description here

Ruhi Goktas
  • 183
  • 3
  • 15

2 Answers2

1

First, DateTime structs weren't properly created from given strings. As your message in red states those strings were converted to 1.1.1910 and 1.1.2060 DateTimes. You should go with CustomValidation attribute.

Second, there might be a problem with converting 01.01.2014 to DateTime at server side. Bear in mind you might be using a specific culture that plays a role in conversions and bindings.

Community
  • 1
  • 1
Marcin Wachulski
  • 567
  • 4
  • 14
0

To fix this, we can create a custom DateRangeAttribute. Here are the steps 1. Right click on the project name in solution explorer, and add "Common" folder. 2. Right click on the "Common" folder and add a class file with name = DateRangeAttribute.cs 3. Copy and paste the following code in DateRangeAttribute.cs class file.

using System;
using System.ComponentModel.DataAnnotations;

namespace MVCDemo.Common
{
    public class DateRangeAttribute : RangeAttribute
    {
        public DateRangeAttribute(string minimumValue)
            : base(typeof(DateTime), minimumValue, DateTime.Now.ToShortDateString())
        {

        }
    }
}
  1. Finally decorate "HireDate" property with our custom DateRangeAttribute as shown below. Notice that, we are only passing the minimum date value. Maximum date value will be today's date. Please note, DateRangeAttribute is present in MVCDemo.Common namespace.

    [DateRange("01/01/2000")] [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)] public DateTime HireDate { get; set; }

Ruhi Goktas
  • 183
  • 3
  • 15
  • Firstly, this doesn't answer the question as to why the strings he passed in didn't work - he didn't say anything about using the current date as the maximum. Secondly, this isn't a very good way to do this - validation attributes can be cached and some applications may run for many days or even years between reboots. This would only let you select dates up to when the validator happened to be instantiated which could lead to subtle bugs. You should just create a fully custom implementation to do this instead of going off of `RangeAttribute`. – Mike Marynowski Dec 05 '18 at 06:10