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?
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.
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.
One approach would be to accept the date as a string and then manipulate it in the controller to the correct locale/culture.
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.