2010-03-30 7 views
15

Kurz und gut Version führt:decimal.TryParse() Tropfen "1"

Auf einer Maschine aus etwa hundert Prüfmaschinen decimal.TryParse() ist die Umwandlung "1,01" bis 0,01


okay, das wird verrückt klingen, aber mit mir tragen ...

wir haben eine Client-Anwendungen haben, die mit einem Webdienst über JSON in Verbindung steht, und dass Dienst gibt einen Dezimalwert als Zeichenfolge so speichern wir es als String in unserem Modellobjekt:

[DataMember(Name = "value")] 
public string Value { get; set; } 

Wenn wir diesen Wert auf dem Bildschirm wird es auf eine bestimmte Anzahl von Dezimalstellen formatiert angezeigt werden soll. Also ist der Prozess, den wir verwenden, String -> Dezimal, dann Dezimal -> String.

Die Anwendung ist derzeit Endprüfung unterzogen und auf mehr als 100 Maschinen ausgeführt werden, wo dies alles funktioniert gut. Jedoch auf einen Maschine, wenn der Dezimalwert eine führende ‚1‘ hat, dann wird es durch eine Null ersetzt. Ich fügte hinzu, um den Code einfach Protokollierung, so dass es wie folgt aussieht:

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; 
} 

Auf meinem Rechner - jeder jeden anderer Client-Rechner - die Logfile Ausgabe lautet:

  • Original-String-Wert: 1,010000
  • Parsed Dezimalwert: 1,010000
  • Formatierte String-Wert: 1,01

Auf der defekten Maschine ist die Ausgabe:

  • Original-String-Wert: 1,010000
  • Analysierte Dezimalwert: 0,010000
  • Formatierter String-Wert: 0,01

es also würde erscheinen, dass die decimal.TryParse-Methode fehlerhaft ist.

Dinge, die wir versucht haben:

  • Deinstallation und Neuinstallation der Client-Anwendung
  • Deinstallation und Neuinstallation von .net 3.5 sp1
  • Vergleicht man die defekten regionalen Einstellungen der Maschine für Zahlen (mit English (United Kingdom)) zu denen einer Arbeitsmaschine - keine Unterschiede.

Hat jemand so etwas gesehen oder irgendwelche Vorschläge? Ich bin aus Ideen schnell laufen ...


Während ich schreibe dies einige weitere Informationen kam: einen String-Wert von „10000“ Passing zu konvertieren.ToInt32() 0 zurück, so dass auch die führenden 1.


Weitere Tests auf Kommentare basierend zu fallen scheint:

  • 1,01 -> 0,01
  • 111,01 -> 11.01
  • 123,01 -> 23,01
  • 231,01 -> 231,01
  • 01,01 -> 1,01

So scheint es, dass es nur 1s und nur betrifft, wenn sie das erste Zeichen der Zeichenfolge sind. Sehr merkwürdig, aber zumindest ist es konsistent.

+1

Schrägen. Was passiert mit anderen Ziffern wie "123" oder "321"? –

+0

Schlechtes RAM in der Maschine? Hast du versucht etwas wie memtest86 zu laufen? –

+0

Dies ist eine wirklich schlechte Idee, aber wenn Sie mit einer Null vor-Pad ...? – spender

Antwort

16

Ich bin in der Lage, Ihre Ergebnisse zu reproduzieren. Bedenken Sie:

public NumberFormatInfo OneIsPositiveSignFormat() 
{ 
    NumberFormatInfo custom = new NumberFormatInfo(); 
    custom.PositiveSign = "1"; 
    return custom; 
} 

Und dann:

if (decimal.TryParse(value, NumberStyles.Number, OneIsPositiveSignFormat(), out val)) 

Die Sache ist die: Regional Settings zeigt nicht die aktuelle positives Zeichen und vor allem: Sie sind nicht die Kultur festgelegt haben, wenn die Anzahl Parsen .

Der Wert kann von verschiedenen Orten kommen: Es kann als das System standardmäßig aus der Registrierung kommen, oder die Standardeinstellungen wurden von Code könnten:

CultureInfo customCulture = (CultureInfo)CultureInfo.InvariantCulture.Clone(); 
customCulture.NumberFormat = OneIsPositiveSignFormat(); 
Thread.CurrentThread.CurrentCulture = customCulture; 
+1

Interessante Antwort, aber es wirft die Frage auf, dass, wenn die regionalen Einstellungen nicht erlauben, das positive Vorzeichen zu setzen, und die regionalen Einstellungen des OP die gleichen wie die anderen Maschinen sind, wie konnte das positive Zeichen geändert werden? Ich stimme dir nicht zu, es passt perfekt zu den Beispielen, ich bin nur neugierig. –

+2

Und wir haben einen Gewinner! Habe gerade den folgenden Code auf seinem Computer ausgeführt: Console.WriteLine (System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PositiveSign); und es gibt "1" aus. Jetzt müssen Sie nur herausfinden, wie Sie das ändern können ... –

+0

Ich wette, es war ein Drittanbieter-Programm, das dies getan hat. Was für eine Ungeheuerlichkeit. – Kugel

-1

sehen, wie die regionalen Einstellungen für diesen Computer eingestellt sind, könnte es sein, dass "." wird als Tausendertrennzeichen nicht als Dezimaltrennzeichen gesetzt. Verwenden Sie Decimal.TryParse (String, NumberStyles, IFormatProvider, out Decimal val) und übergeben Sie NumberFormatInfo, das mit dem Dezimaltrennzeichen "."

+2

OP hat bereits gesagt, dass es keine Unterschiede in den regionalen Einstellungen gibt - und wenn 1.000 eingegeben wurde, wenn '.' ein Tausendertrennzeichen war, würde es 1000 ergeben, nicht 0. –

Verwandte Themen