I have a fairly large MVC Project I have been working with for some time. Suprisingly I have only just created an action with nullable date time parameters, IE:
public ActionResult MyAction(DateTime? startDate, DateTime? endDate)
Now when I pass a date formatted for the UK these parameters are NOT populated. When the date is formatted for the US they are.
If I pass a UK formatted date that is compatible with the US format the parameter is populated but the month/day are switched round.
In the UK and most of Europe dates are listed Day/Month/Year. IE: 20th Aug 2009 is 20/08/2009 NOT 08/20/2009 as it is un the US.
So:
.../MyAction?startDate=01/01/2009
Works and I get first of Jan 2009.
.../MyAction?startDate=13/01/2009
Fails - start date parameter is empty.
.../MyAction?startDate=05/01/2009
Fails - start date parameter is populated but with 1st May 2009, when it should be 5th Jan 2009.
It's pretty easy to guess what is happening here. For some reason the ASP.NET MVC framework is not picking up the locale when attempting to parse the date. Is this a known bug? If so is there a planned fix?
I have got round this for now by hacking the action so the dates are string parameters that I then parse myself... Smells bad as you can imagine so I would love a fix for this please...
The problem with automatically parsing dates from the query string with the user's locale is that we have no idea where they came from. If the server is putting dates into URLs, it clearly can't do that using the user's locale, because then you will have
non-canonical URLs (and worse, URLs which point to the wrong content depending on the user's locale). In fact, even if the date came from the user, you're still generating a non-canonical URL which the user could pass along to another user and inadvertantly
send them to the wrong place.
When the values come from POSTed form fields, we know they came from the user and can then apply the user's locale when binding.
I can understand what you are saying but I am still a little confused. In my specific scenario I have two fields on a page and a button. When the user hit's the button the client side javascript pulls the dates from the form and opens a new browser window
with the dates in the query string.
Now I get what you are saying about the user's locale, but what I don't understand is, when I test this on a development machine which is set up to UK the dates are parsed using the US format.
I would have thought the MVC Framework should either pass the dates using the server's locale or, because of the reasons you mention, throw and exception because it can not determine which locale should be used to parse the dates.
I am working on a UK box, with both the client and server running under the UK locale and yet my dates are being treated a US dates...
Now I get what you are saying about the user's locale, but what I don't understand is, when I test this on a development machine which is set up to UK the dates are parsed using the US format.
MVC always uses the invariant locale to parse URL query string parameters, so it doesn't matter what locale the server is in.
Right... and the 'Invariant' culture is based upon the US formats?
I guess the way around this is to either parse the dates myself as I am currently doing, or pass the dates in an unambiguous format, IE: '01 Jun 2009'.
In my case I had to change the parameters to strings then parse them manually in the action. This is not ideal but I had to get something out the door asap so that's what I have at present. When I have some more time I intend to change the client side code
to parss the dates in an unambiguous format: IE: '01 Apr 2009' so the day and month cannot be mixed up.
Here is the code I currently have (NOTE: This is a temp workaround so the code is not ideal, and it assumes the user is in the same locale as the server):
public ActionResult MyAction(string startDate, string endDate)
{
DateTime startDateParsed, endDateParsed;
DateTime? startDateParsedNullable = null, endDateParsedNullable = null;
if (DateTime.TryParse (startDate, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out startDateParsed))
startDateParsedNullable = startDateParsed;
if (DateTime.TryParse(endDate, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out endDateParsed))
endDateParsedNullable = endDateParsed;
public class MyDateTimeModelBinder : IModelBinder {
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
string key = bindingContext.ModelName;
ValueProviderResult result;
if (bindingContext.ValueProvider.TryGetValue(key, out result)) {
// the second parameter is the culture to use for conversion.
// you may want to have a try / catch around the ConvertTo() call,
// e.g. the user didn't type in a valid date.
return result.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
}
else {
// no value found
return null;
}
}
}
In Global.asax Application_Start(), register it with a call to:
ModelBinders.Binders[typeof(DateTime)] = new MyDateTimeModelBinder();
Hope this helps,
~ Levi
Marked as answer by leather on Aug 27, 2009 08:52 AM
leather
Member
116 Points
27 Posts
Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 20, 2009 11:02 AM|LINK
Hi There,
I have a fairly large MVC Project I have been working with for some time. Suprisingly I have only just created an action with nullable date time parameters, IE:
public ActionResult MyAction(DateTime? startDate, DateTime? endDate)
Now when I pass a date formatted for the UK these parameters are NOT populated. When the date is formatted for the US they are.
If I pass a UK formatted date that is compatible with the US format the parameter is populated but the month/day are switched round.
In the UK and most of Europe dates are listed Day/Month/Year. IE: 20th Aug 2009 is 20/08/2009 NOT 08/20/2009 as it is un the US.
So:
.../MyAction?startDate=01/01/2009
Works and I get first of Jan 2009.
.../MyAction?startDate=13/01/2009
Fails - start date parameter is empty.
.../MyAction?startDate=05/01/2009
Fails - start date parameter is populated but with 1st May 2009, when it should be 5th Jan 2009.
It's pretty easy to guess what is happening here. For some reason the ASP.NET MVC framework is not picking up the locale when attempting to parse the date. Is this a known bug? If so is there a planned fix?
I have got round this for now by hacking the action so the dates are string parameters that I then parse myself... Smells bad as you can imagine so I would love a fix for this please...
Thanks.
bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 20, 2009 04:33 PM|LINK
The problem with automatically parsing dates from the query string with the user's locale is that we have no idea where they came from. If the server is putting dates into URLs, it clearly can't do that using the user's locale, because then you will have non-canonical URLs (and worse, URLs which point to the wrong content depending on the user's locale). In fact, even if the date came from the user, you're still generating a non-canonical URL which the user could pass along to another user and inadvertantly send them to the wrong place.
When the values come from POSTed form fields, we know they came from the user and can then apply the user's locale when binding.
leather
Member
116 Points
27 Posts
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 24, 2009 01:59 PM|LINK
Hi Bradwils,
Thanks for your response.
I can understand what you are saying but I am still a little confused. In my specific scenario I have two fields on a page and a button. When the user hit's the button the client side javascript pulls the dates from the form and opens a new browser window with the dates in the query string.
Now I get what you are saying about the user's locale, but what I don't understand is, when I test this on a development machine which is set up to UK the dates are parsed using the US format.
I would have thought the MVC Framework should either pass the dates using the server's locale or, because of the reasons you mention, throw and exception because it can not determine which locale should be used to parse the dates.
I am working on a UK box, with both the client and server running under the UK locale and yet my dates are being treated a US dates...
Thanks,
L.
bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 24, 2009 06:49 PM|LINK
MVC always uses the invariant locale to parse URL query string parameters, so it doesn't matter what locale the server is in.
leather
Member
116 Points
27 Posts
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 25, 2009 08:26 AM|LINK
Right... and the 'Invariant' culture is based upon the US formats?
I guess the way around this is to either parse the dates myself as I am currently doing, or pass the dates in an unambiguous format, IE: '01 Jun 2009'.
bec.username
Member
163 Points
83 Posts
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 26, 2009 06:26 AM|LINK
What was the solution to this question? I have the same issue.
leather
Member
116 Points
27 Posts
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 26, 2009 07:54 AM|LINK
Hi Bec,
In my case I had to change the parameters to strings then parse them manually in the action. This is not ideal but I had to get something out the door asap so that's what I have at present. When I have some more time I intend to change the client side code to parss the dates in an unambiguous format: IE: '01 Apr 2009' so the day and month cannot be mixed up.
Here is the code I currently have (NOTE: This is a temp workaround so the code is not ideal, and it assumes the user is in the same locale as the server):
public ActionResult MyAction(string startDate, string endDate) { DateTime startDateParsed, endDateParsed; DateTime? startDateParsedNullable = null, endDateParsedNullable = null; if (DateTime.TryParse (startDate, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out startDateParsed)) startDateParsedNullable = startDateParsed; if (DateTime.TryParse(endDate, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out endDateParsed)) endDateParsedNullable = endDateParsed;bec.username
Member
163 Points
83 Posts
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 26, 2009 09:25 AM|LINK
Thanks for the help. Would it be possible to use a custom model binder to do this?
My app is actually intended for an intranet environment so assuming that the client and server are in the same locale is ok.
levib
Star
7702 Points
1099 Posts
Microsoft
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 26, 2009 05:50 PM|LINK
Sure. Here's a binder to pull this off:
public class MyDateTimeModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { string key = bindingContext.ModelName; ValueProviderResult result; if (bindingContext.ValueProvider.TryGetValue(key, out result)) { // the second parameter is the culture to use for conversion. // you may want to have a try / catch around the ConvertTo() call, // e.g. the user didn't type in a valid date. return result.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture); } else { // no value found return null; } } }In Global.asax Application_Start(), register it with a call to:
Hope this helps,
~ Levi
bec.username
Member
163 Points
83 Posts
Re: Nullable DateTime Action Parameters Parsed in US format irrespective of locale?
Aug 27, 2009 01:09 AM|LINK
Great! Thanks heaps