Search code examples
asp.netasp.net-mvc-5jquery-ui-datepickerdate-formatdatefield

ASP.NET MVC5 stores date in wrong format


last days I have a quite hard time to convince MVC5 project to work with dates as I would like to. After intensive googling I've tried numerous attepmts to make it work properly, but without success.

Here is the problem:

I need to display and edit dates on my webpage in format dd.MM.yyyy (i.e. 15.07.2015). For editing I also need to use jquery ui datepicker. The thing here is that I've been able to successfully set that datepicker to display date in requested format, also the jquery validation is now correctly validating the date in given format. So as for UI so far so good. The problem appeared in moment, when I clicked submit button - there was an error message like:

The value '15.07.2015' is not valid for Start Date.

After brief investigation I've found that when the date is passed to server it has switched format - instead of dd.MM.yyyy the date is treated like MM.dd.yyyy. In other words the error pops up only when the day part of date is higher than 12.

Here are some highlights from my code:

In my model for date I have this:

[Required]
[Display(Name = "Start Date")]
[DataType(DataType.Date)]
[UIHint("Date")]
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
public DateTime DateStarts;

Which I believe is everything I need to do to make that date display in specified format and also force users to fill the textbox with date in right format.

As given in [UIHint("Date")], I have my own template for rendering textbox for editing date. The implementation of that template is following:

@model Nullable<DateTime>

@{

DateTime dt = DateTime.Now;

if (Model != null)
{
    dt = (System.DateTime)Model;
}

@Html.TextBox("", dt.ToString("dd.MM.yyyy"), new { @class = "form-control datecontrol", type = "text", data_val_date = "Field must have format dd.MM.yyyy" })
<i class="fa fa-calendar form-control-feedback lowerzindex"></i>

}

The jquery datepicker has following implementation:

 $('.datecontrol').datepicker({
    onClose: function () { $(this).valid(); },
    minDate: "-1M",
    dateFormat: "dd.mm.yy",
});

So even the datepicker knows how the format should look like.

The last component is the validation by jquery.validation:

 $.validator.addMethod(
    'date',
    function (value, element, params) {
        if (this.optional(element)) {
            return true;
        };
        var result = false;
        try {
            $.datepicker.parseDate('dd.mm.yy', value);
            result = true;
        } catch (err) {
            result = false;
        }
        return result;
    },
    ''
);

I know that the date is passed to server in some culture neutral format, but I thought that when I decorated code on numerous places with the requested format, this will ensure that the conversion into that culture neutral format will be done right. Or am I missing something else ?

Thanks


Solution

  • Your problem lies in the fact that you have not set proper Culture for your application. Your request end-up executing under culture that has month-day-year order (probably under en-US) causing you a problem.

    The easiest solution is to set set the culture that actually has day-month-year order and . as date separator in your web.config, for example:

    <configuration>
       <system.web>
           <globalization uiCulture="de-DE" culture="de-DE" />
           ...
    

    https://msdn.microsoft.com/en-us/library/bz9tc508%28v=vs.140%29.aspx

    The MVC uses current culture when parsing and binding posted data to your models/parameters. It is advised to use same date separator across entire scope - html, client, javascript, server culture, ...