18

I am using MVC 4 and am wondering if there is a bug in the Datetime culture info?

I am trying to get Australian dates to work (dd/MM/yyyy), but it keeps saying that the date format is wrong, even after puttig a globalizaton to the web.config. I thought it was an error with my code, but even if you start a new project it still happens.

I started a new MVC 4 Web application.

Added the following to the web.config file

<globalization culture="en-AU" uiCulture="en-AU" />

Then I added the following to the AccountModels.cs file:

[DataType(DataType.DateTime)]
[Required(ErrorMessage="Date is required")]
public DateTime? MyDate { get; set; }

Then I added the following to the Register.cshtml file:

<li>
    @Html.LabelFor(m => m.MyDate)
    @Html.TextBoxFor(m => m.MyDate)
</li>

Run the application, go to the register page, try a date like 26/03/2013 and it says not a valid format.

Please help.

asymptoticFault
  • 4,491
  • 2
  • 19
  • 24
user2206329
  • 2,792
  • 10
  • 54
  • 81

4 Answers4

24

Try adding this attribute to your MyDate property:

[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]

Though setting the culture in the web.config should do it, this should force it into that format.

UPDATE

Ok, so the above answer doesn't really solve the issue, though it is important if you do want to change the format of how the date is initially displayed. An important note is that the DisplayFormat attribute is not picked up by the TextBoxFor helper but it is by the EditorFor helper.

Anyway, on to the real solution. The problem is the jQuery validation not accounting for the culture when parsing a date. If you turn off the client side validation the date is parsed just fine on the server that is aware of the culture.

The fix is to override the jQuery validation for date and include an additional jQuery globalization plugin. You can find the globalize plugin here. You can also easily download the plugin using the Nuget Package Manager as well. I just opened the package manager, selected the Online tab on the left and typed "globalize" into the search and it was the first result. Once you have it installed I included these two files:

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

You can either include them directly using a script tag or place them in a bundle, perhaps with the other jQuery validation files.

Once you have those you will need to add the following script to override the jQuery validation for date:

<script type="text/javascript">
    $(function () {
        $.validator.methods.date = function (value, element) {
            Globalize.culture("en-AU");
            // you can alternatively pass the culture to parseDate instead of
            // setting the culture above, like so:
            // parseDate(value, null, "en-AU")
            return this.optional(element) || Globalize.parseDate(value) !== null;
        }
    });
</script>

And that's it, that should do the trick. I credit this solution to this answer: JQuery Validation and MVC 3. How to change date format I just also wanted to provide some more explanation specific to your issue.

Community
  • 1
  • 1
asymptoticFault
  • 4,491
  • 2
  • 19
  • 24
  • that didn't work. Can you try by creating a new project and following the steps please? I am going insane trying to sort this issue.. is it an issue with my install? my machine? I am using IIS Express, as I am running it straight from vs2012.. could that be the issue? – user2206329 Sep 01 '13 at 01:06
  • here is a link to my project, its just a brand new project with the above mentioned changes.. https://dl.dropboxusercontent.com/u/87611366/MvcApplication2.zip – user2206329 Sep 01 '13 at 01:32
  • I'll give it a try locally and see what happens. I don't have much experience with globalizing applications or changing the culture but this should be all that is necessary. – asymptoticFault Sep 01 '13 at 01:49
  • 1
    Ok, I believe I got it! Turns out setting the culture in the *web.config* is pretty much all you need to do, **UNLESS** you are using jQuery validation. When I left out the client side validation the date worked fine, when I included it it complained about the format as you said. The fix is to override the jQuery validation for date and include an additional jQuery globalize library that allows the date to be parsed in other culture formats. Check out the update in my answer for a full explanation. – asymptoticFault Sep 01 '13 at 02:40
  • asymptoticFault - You are awesome, thank you so much for that. It worked. You are a scholar and a gentleman. Thanks again, your help has been very very appreciated. – user2206329 Sep 02 '13 at 02:44
  • You are very welcome :-) Always happy to help someone find the right solution. – asymptoticFault Sep 02 '13 at 03:05
  • Answer appreciated :-) – Matt Mitchell Nov 10 '13 at 13:00
  • I would recommend disabling MVC client side validation and rolling your own if you really needed. It's black box full of black magic. – Kugel Jan 14 '14 at 00:09
  • It worked ok, but when I downloaded Globalizejs with Nuget (https://www.nuget.org/packages/jquery-globalize/) the file "globalize.culture.en-AU.js" was not there, but is not necessary. It worked ok just with "globalize.js" – Daniel Silva Dec 22 '16 at 14:59
1

Accepted answer is not up to date. My finally working solution:

$(function () {
    $.validator.methods.date = function (value, element) {
        return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
    }
});

You have to include before:

@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")

You can install moment.js using:

Install-Package Moment.js
lukyer
  • 7,595
  • 3
  • 37
  • 31
0

What about creating a proxy function?

var _date = $.validator.methods.date;

$.validator.methods.date = function (value, element) {
    return _date.call(this, Globalize.parseDate(value), element);
};
Andrew Gunn
  • 95
  • 1
  • 8
0

In Additional Turkey Culture that is below.

<globalization 
fileencoding="utf-8" 
requestencoding="utf-8" 
responseencoding="utf-8" 
culture="tr-TR" 
uiculture="tr-TR"/>
Metin Atalay
  • 1,375
  • 18
  • 28