0

I have tried several methods, but I don't know why, but this is confusing me.

Model:

public class SearchViewModel
    {        
        [DisplayName("Date from:")]
        //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{dd.MM.yyyy}")]
        public DateTime? DateFrom { get; set; }

        [DisplayName("Date to:")]
        public DateTime? DateTo { get; set; }
    }

View:

@using (Html.BeginForm("SearchResult", "Search", FormMethod.Get, new { @id = "searchForDate" }))
{
    <div id="criterias">


        @Html.LabelFor(m => m.DateFrom)
        @Html.EditorFor(m => m.DateFrom, new { htmlAttributes = new { @class = "searchinput datepicker" } })

        @Html.LabelFor(m => m.DateTo)
        @Html.EditorFor(m => m.DateTo, new { htmlAttributes = new { @class = "searchinput datepicker" } })
</div>
    <button type="submit" class="btn btn-danger" style="background-color:#991821; margin-top:15px;" id="search">Search</button>
}

The problem:

The datepicker works fine. When I am loading the page, I click into the EditorFor DateFrom box and picking a date, lets say 02.01.2019 (2nd of January 2019). When I click on submit it is jumping into the controller action.

In the controller action model.DateFrom is changing day and month. That means it suddenly is 01.02.2019 (2nd of February), which is totally wrong. When I pick a day above 12 the model.DateFrom is invalid.

I tried the following things:

  • Insert [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{dd.MM.yyyy}")] in the model
  • added <system.web> <globalization uiCulture="de-DE" culture="de-DE" /></system.web> in my Web.config
  • added the InternationalizationAttribute --> CurrentCulture and CurrentUICulture in the Controller
  • tried to modify the EditorFor to TextboxFor with several settings: see Date only from TextBoxFor()

I also came across this article: MVC DateTime binding with incorrect date format but unfortunately my know how isn't that good.

I don't know why this is happening and more importent WHERE this is happening? I put my breakpoint into the Internationalization class, put the bp direct under the SearchController action. nothing helps. When I click the submit button, day and month are chaning the position...

  • 1
    It is best to treat dates and times as strings. The problem you are likely running into is a difference in the locale of the client and the locale of the server. Many European countries use `dd-MM-YYYY`, whereas the US will use `MM-dd-YYYY`. If you don't account for this through localization parsing, etc., you'll likely get this issue. I think the "How to fix it" is highly dependent on the scenario, but I'd use strings and skip implicit model binding from string to date. – ps2goat Feb 25 '19 at 22:08
  • Okay I did it. Changed it to string and now it is working. But I wonder which mechanism is fired or what happend between pressing the Search button and firing the action method. Between clicking on search and calling the action method there is the change of day/month. I don't know why. – Spedo De La Rossa Feb 26 '19 at 09:38
  • I migrated my comment to an answer, since it helped you. I also added some additional info that may be helpful. – ps2goat Feb 26 '19 at 17:26

2 Answers2

1

You could try checking the "accept-language" HTTP Request Header. Just pop open the dev tools Network tab and click on your request headers for the search.

accept-language:en-US,en;q=0.9

Is it what was expected?

Also, please see this question:

MVC DateTime binding with incorrect date format

and specifically, this resource from the answer:

https://weblogs.asp.net/melvynharbour/mvc-modelbinder-and-localization

Hope it helps!

edit: Also, if you aren't already, I recommend using UTC for all server side dates. Client side dates can/should be local time.

Andrew Meservy
  • 103
  • 2
  • 9
1

* Moved my comment to an answer, with some additional information.

It is best to treat dates and times as strings. The problem you are likely running into is a difference in the locale of the client and the locale of the server. Many European countries use dd-MM-YYYY, whereas the US will use MM-dd-YYYY. If you don't account for this through localization parsing, etc., you'll likely get this issue. I think the "How to fix it" is highly dependent on the scenario, but I'd use strings and skip implicit model binding from string to date.

Updated Info

There's a longer explanation, but basically the current culture uses the default format on the server, but the browser's current culture uses a different format. (As stated above.) You can change the culture, but that may be difficult depending on your expected audience and the size of your team. I've tested with this in a limited scenario, but wouldn't necessarily recommend it due to several potentially untested pitfalls. (Your QA, unit test, etc., would have to include all possible cultural differences, like interchange commas and decimal points in numeric values [5.00 vs 5,00], date formats, etc.)

My preferred approach is to use a common contract format for all potential issues, and then the clients (your web UI) can format the value correctly before sending it to the back end / API. For dates and date times, I use ISO 8601 format and have the accepted variable type be a string in the back end.

The date value would be listed as, e.g., 2019-02-26 (YYYY-MM-dd). I prefer this for a few reasons:

  • The date format does not change between formats.
  • Strings do not have their value parts parsed incorrectly.
  • UTC / offset issues do not occur between the client and the server.
  • The ISO format string is sortable.
ps2goat
  • 8,067
  • 1
  • 35
  • 68