Right now I have a ViewModel with a property double Maximum
. On the view side it's kept in a hidden input to help with unobtrusive validation.
When post backing the values, the binding silently fails. I had to put a breakpoint on this line:
if(ModelState.IsValid)
and check which ModelState
property had an error. Then I found that this double Maximum
property had an error with the following message:
The parameter conversion from type 'System.String' to type 'System.Double' failed. See the inner exception for more information.
On the view side inspecting the HTML
with Firebug I can see that the hidden input has this value:
1.79769313486232E+308
which correctly represents double.MAX constant.
I found this Scott Hanselman post from Jan/2005 (almost 9 years ago) which deals with something similar:
Is there something wrong with my app config or this direct conversion from string
back to double
is not supported? I think it should handle it without errors.
Note: I tried changing the hidden input value with Firebug and did as Scott mentions on his post: I subtracted 1 from the last digit...
1.79769313486231E+308
and did a postback again just to find the model binder handled it correctly this time.
I'm using @Html.HiddenFor
to create the hidden input.
After carefully reading Scott's post I saw that he mentions the round-trip specifier. I also found an example here on StackOverflow.
The R stands for "round-trip". From MSDN:
This format is supported only for the Single and Double types. The round-trip specifier guarantees that a numeric value converted to a string will be parsed back into the same numeric value.
So I did this:
@Html.HiddenFor(m => m.Maximum,
new { Value = Model.Maximum.ToString("R") })
Now this gives me a double.MAX
string representation that can be round-tripped back to a double
on the controller side:
1.7976931348623157E+308
Nice... problem solved.
Hope it helps anyone that might face this same problem in the future.
How interesting this is?!
1.79769313486232E+308 // double.MAX
1.7976931348623157E+308 // double.MAX.ToString("R")
It's worth mentioning that all this is also applicable to double.MIN
.