InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Two-way databinding with ASP.NET struggles with DateTime conversion

When you create a website with ASP.NET 2.0 and use the two-way databinding with an object datasource, you might have come accross this error:

Cannot convert value of parameter 'Created' from 'System.String' to 'System.DateTime'

This happens when you bind a data field with a DateTime datatype to a textbox, either with the BoundField method or with the <%# Bind("...") %> keyword.

One additional requirement for this error to happen is that the user local is set to non-english (respectively the invariant culture).

Digging deeper into the ObjectDataSourceView with Reflector, I found the cause for this strange behavior: The Bind-keyword or the BoundField class formats the string according to a format string. This, by default that a DateTime is displayed in german as follows:

29.11.2006 09:12:24 (e.g. dd.MM.yyyy hh:mm:ss).

When ASP.NET attempts to write back the changes made by the user, it reads the value from the textbox and tries to convert it from a string to a DateTime object.  It does this by retrieving the TypeConverter responsible for the DateTime class and calls typeConverter.ConvertFromInvariantString(). This obviously fails with a non-english string and produces the error seen above.

The default.aspx file in the attached Visual Studio Solution shows this error.

Workaround

The workaround I'm using for this issue is to attach an Item_Updating event to the data control (DetailsView, FormView, etc). This event then converts the dataformat to an invariant datetime string:

    1 protectedvoid DetailsView1_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)

    2 {

    3     e.NewValues["Created"] = DateTime.Parse((string) e.NewValues["Created"]).ToString(CultureInfo.InvariantCulture);

    4 }

The solution.aspx file implements this workaround.

Downloads

TwoWayDataBinding.zip (18,427 Bytes)
Example application which demonstrates the described problem and workaround

Technorati:

Posted by Henning Krause on Wednesday, November 29, 2006 12:00 AM, last modified on Wednesday, November 29, 2006 12:00 PM
Permalink | Post RSSRSS comment feed

Comments (4) -

On 2/7/2009 6:26:01 AM Sam Australia wrote:

Sam

One additional requirement for this error to happen is that the user local is set to non-english (respectively the invariant culture).
What do you mean non-english? Most of the English speaking countries in the world apart from the USA use a consistent date format (day/month/year or year/month/day).

If the web.config file is configured correctly to handle a localised date format, this error should not occur.

&amp;amp;lt;configuration&amp;amp;gt;
  &amp;amp;lt;system.web&amp;amp;gt;
    &amp;amp;lt;globalization culture=&amp;amp;quot;en-AU&amp;amp;quot; uiCulture=&amp;amp;quot;en-AU&amp;amp;quot; /&amp;amp;gt;
  &amp;amp;lt;/system.web&amp;amp;gt;
&amp;amp;lt;/configuration&amp;amp;gt;

Furthermore, when the control is bound to a date field, a custom format string can be used to avoid this error.

&amp;amp;lt;%# Bind(&amp;amp;quot;...&amp;amp;quot;,&amp;amp;quot;{0:dd/MM/yyyy}&amp;amp;quot;) %&amp;amp;gt;

Upon updating or inserting, this format string should be used to parse the string to a date.

On 2/27/2009 3:11:44 PM gustavo castro Brazil wrote:

gustavo castro

EXCELLENT!!!!

I had the same problem and i was trying to solve it for a long time ....


thks...

(Microsoft should do something about this ...)

On 2/27/2009 3:14:07 PM gustavo castro Brazil wrote:

gustavo castro

Obs.:
(even setting the format (Bind(&amp;amp;quot;datafileld&amp;amp;quot;, &amp;amp;quot;{0:dd/MM/yyyy}&amp;amp;quot;) and cultures correctly (ex. Culture=&amp;amp;quot;pt-BR&amp;amp;quot; + uiCulture=&amp;amp;quot;pt-BR&amp;amp;quot; - in WebConfig and overloading InitCulture()), the error happens ...

On 4/1/2009 6:05:17 AM siraj Saudi Arabia wrote:

siraj

i too have the same problem. my windows xp set to english/arabic bilingual. however the first method works well
by using itemupdate event. Infact it is a additional job for programmers but microsoft should work around and
solve it.