Short and sweet version:
On one machine out of around a hundred test machines decimal.TryParse() is converting "1.01" to 0.01
Okay, this is going to sound crazy but bear with me...
We have a client applications that communicates with a webservice through JSON, and that service returns a decimal value as a string so we store it as a string in our model object:
[DataMember(Name = "value")]
public string Value { get; set; }
When we display that value on screen it is formatted to a specific number of decimal places. So the process we use is string -> decimal then decimal -> string.
The application is currently undergoing final testing and is running on more than 100 machines, where this all works fine. However on one machine if the decimal value has a leading '1' then it is replaced by a zero. I added simple logging to the code so it looks like this:
Log("Original string value: {0}", value);
decimal val;
if (decimal.TryParse(value, out val))
{
Log("Parsed decimal value: {0}", val);
string output = val.ToString(format, CultureInfo.InvariantCulture.NumberFormat);
Log("Formatted string value: {0}", output);
return output;
}
On my machine - any every other client machine - the logfile output is:
- Original string value: 1.010000
- Parsed decimal value: 1.010000
- Formatted string value: 1.01
On the defective machine the output is:
- Original string value: 1.010000
- Parsed decimal value: 0.010000
- Formatted string value: 0.01
So it would appear that the decimal.TryParse method is at fault.
Things we've tried:
Has anyone seen anything like this or has any suggestions? I'm quickly running out of ideas...
While I was typing this some more info came in: Passing a string value of "10000" to Convert.ToInt32() returns 0, so that also seems to drop the leading 1.
Further tests based on comments:
So it would appear that it only affects 1s and only if they are the first character of the string. Very odd, but at least it's consistent.
I am able to reproduce your results. Consider:
public NumberFormatInfo OneIsPositiveSignFormat()
{
NumberFormatInfo custom = new NumberFormatInfo();
custom.PositiveSign = "1";
return custom;
}
And then:
if (decimal.TryParse(value, NumberStyles.Number, OneIsPositiveSignFormat(), out val))
The thing is: Regional Settings does not show you the current positive sign, and mainly: you did not set the culture when parsing the number.
The value may come from various locations: It may have come from the registry as the system defaults, or the defaults could have been set by code:
CultureInfo customCulture = (CultureInfo)CultureInfo.InvariantCulture.Clone();
customCulture.NumberFormat = OneIsPositiveSignFormat();
Thread.CurrentThread.CurrentCulture = customCulture;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With