6

In my ASP MVC 5 web application, I need to display a date in a specific format. When the page loads, the text is formatted correctly. But if you edit the value or simply try to post, the validation error is shown:

enter image description here

The field is defined like this:

        @*Creation*@
    <div class="form-group">
        @Html.LabelFor(model => model.Creation, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.Creation, "{0:dd/MM/yyyy}", new { @class = "form-control"})
            @Html.ValidationMessageFor(m => m.Creation)
        </div>
    </div>

The viewmodel property is defined as:

        [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    [Display(Name = "Creation", ResourceType = typeof(Resources.Resources))]
    public DateTime Creation { get; set; }

The screenshot was created using Firefox browser. If I do the same on Edge, the validation passes, but the biding of this property on the post method is invalid (a default date value).

How can I fix this issue?

Igor Kondrasovas
  • 1,479
  • 4
  • 19
  • 36
  • 1
    As Matt Spinks has noted, this a `jquery.validate.js` issue (which validates dates based on `MM/dd/yyyy`) and you need to override the validator (refer [this answer](http://stackoverflow.com/questions/30594128/error-in-date-validation-mvc/30609111#30609111) for more detail. –  Feb 02 '17 at 22:53
  • 1
    The reason it works in Edge (and in Chrome) is because you have `[DataType(DataType.Date)]` which generates `type="date"` which means the browsers implementation of a DatePicker will be displayed, but to make that work correctly you need to use `DataFormatString = "{0:yyyy-MM-dd}"` (ISO format) –  Feb 02 '17 at 22:55
  • 1
    Refer also [this answer](http://stackoverflow.com/questions/39677035/date-of-birth-validation-keeps-showing/39682410#39682410) which includes a script you can include in your view for client side validation. –  Feb 03 '17 at 23:03

1 Answers1

9

The problem here is that, behind the scenes, the validation is actually being performed by jQuery. So the key is to tell the jQuery validator that you will be using the dd/MM/yyyy format.

There are a couple ways of doing this. The simplest way is to just override the validator function (for dates) with a simpe tweak:

jQuery(function ($) {
    $.validator.addMethod('date',
    function (value, element) {
      $.culture = Globalize.culture("en-AU");
      var date = Globalize.parseDate(value, "dd/MM/yyyy", "en-AU");
      return this.optional(element) || 
        !/Invalid|NaN/.test(new Date(date).toString());
    });
});

An alternative would be to use a globalization library for jQuery. There is a globalization library that you can use here.

When you have the library, include these files:

globalize.js 
globalize.culture.en-AU.js

Then override the validator function:

<script type="text/javascript">
    $(function () {
        $.validator.methods.date = function (value, element) {
            Globalize.culture("en-AU"); // the UK format
            return this.optional(element) || Globalize.parseDate(value) !== null;
        }
    });
</script>
Matt Spinks
  • 6,380
  • 3
  • 28
  • 47
  • Hi @Matt, I installed the library (via NuGet package), did NOT manually add any files and then override validation function. My location is pt-BR so I replaced "en-AU" to "pt". Now the validation does not get anything. If I type a erroneous date like: 30/12/2016dssfds it does not validate. Besides, the binding is still failing. Any ideas? – Igor Kondrasovas Feb 03 '17 at 16:30
  • You might check to make sure all your files are being included correctly (no 404's). – Matt Spinks Feb 03 '17 at 16:32
  • I tried also the simplest way you suggested (simple tweak) and the result is exactly the same. No validation takes places. I removed the globalize package to make sure it does not influence the tweak. What do you mean by checking for 404´s? – Igor Kondrasovas Feb 03 '17 at 17:31
  • Back to the globalize package approach, I also tried to include globalize.js and globalize.culture.pt.js files in the BundleConfig.cs. But this did not influence the result. – Igor Kondrasovas Feb 06 '17 at 14:20
  • Thank you Matt you saved my day was getting very frustrated with my "blind date" (Razor, Boostrap, jQuery) – Trevor Jan 27 '18 at 08:16