22

My application is setted with pt-BR culture (Date is dd-mm-yyyy) in web.config:

<globalization enableClientBasedCulture="false" requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="iso-8859-15" responseHeaderEncoding="utf-8" resourceProviderFactoryType="string" enableBestFitResponseEncoding="true" culture="pt-BR" uiCulture="pt-BR" />

All DateTime created on my system is in right format, but I created a controller method like that:

public ActionResult Test(DateTime date)
{
}

Calling that method direct in the browser is passing null when the date is with portuguese-br format, like that:

mysite/Test/?date=19/01/2012   => date = null in my controller

mysite/Test/?date=01/01/2012   => date is fine, but in US format (mm-dd-yyyy)

How can I fix that, to accept my date format?

Zanon
  • 29,231
  • 20
  • 113
  • 126
Paul
  • 12,359
  • 20
  • 64
  • 101

4 Answers4

57

There's a gotcha with the default model binder that is not easy to know about but once you know it you no longer make the same mistake:

  • When you use a POST request, the default model binder uses your culture settings to parse the dates.

  • When you use a GET request, the default model binder uses CultureInfo.InvariantCulture to parse the dates and ignores your current culture settings.

Since you are using a GET request and passing the date as a query string parameter, you should format it using the invariant culture format when sending it in the url. The correct way to format your date as a query string parameter is yyyy-MM-dd.

You may take a look at the following blog post which gets into more details.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    If you implement the custom binder, make sure to register it for DateTime? as well, not just DateTime. – Justin Apr 06 '14 at 17:01
  • Hello, Darin. I've encountered the same problem as the original post and your answer and the article quoted helped me to understand the issue but I can't reach an answer yet. I'm working on ASP.NET Core 2.0 but I don't know how to apply the recomendations of the article. Hope you could take a look to this question: https://stackoverflow.com/questions/47442368/routing-datetime-parameter-passing-as-null-empty – Luis Alberto Delgado de la Flo Nov 23 '17 at 04:04
9

As someone who does a lot of work with US companies, I've had a lot of experience with date issues.

My best advice is to choose an unambiguous format when transmitting.

dd-MMM-yyyy

and

yyyy-MM-dd

Are safe bets, and will be successfully parsed by DateTime.Parse(obj).

If changing the date format is not an option, you should look at DateTime.ParseExact, which allows you to specify the exact format string you are after.

Paul Alan Taylor
  • 10,474
  • 1
  • 26
  • 42
2

One approach would be to accept the date as a string and then manipulate it in the controller to the correct locale/culture.

Kevin Junghans
  • 17,475
  • 4
  • 45
  • 62
0

Got the same problem using an @Html.Action(..) in a view. For this situation it can be solved by putting the DateTime in a model:

public class MyModel
{
  public DateTime Value {get;set;}
}

and in the view:

@Html.Action("MyAction", new { myModel })

Note the new { } around the instance of MyModel, this way the DateTime is not converted to a string. This solution only works for Html.Action() and not for Html.ActionLink() or Url.Action() since MVC is doing a myModel.ToString() in the URL.

Marthijn
  • 3,292
  • 2
  • 31
  • 48