2010-03-30 10 views
15

Versión resumida y dulce:decimal.TryParse() cae líder "1"

En una máquina de alrededor de un centenar de máquinas de prueba decimal.TryParse() es la conversión de "1,01" a 0,01


Bien, esto va a sonar loco, pero tengan paciencia ...

Tenemos una aplicación cliente que se comunica con un servicio web a través de JSON, y ese servicio devuelve un valor decimal como cadena, así que lo almacenamos como una cadena en nuestro modelo de objeto:

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

Cuando mostramos ese valor en la pantalla, se formatea a un número específico de decimales. Entonces el proceso que usamos es string -> decimal luego decimal -> string.

La aplicación se encuentra actualmente en pruebas finales y se está ejecutando en más de 100 máquinas, donde todo funciona bien. Sin embargo, en una máquina si el valor decimal tiene un '1' inicial, entonces se reemplaza por un cero. He añadido el registro sencillo para el código por lo que se ve así:

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

En mi máquina - cualquier cualquier otro equipo cliente - la salida del archivo de registro es:

  • valor de cadena original: 1.010000
  • Analizada
  • valor decimal: 1,010000
  • valor de cadena con formato: 1,01

En la máquina defectuosa la salida es:

  • original valor de cadena: 1,010000
  • valor decimal procesado: 0,010000
  • valor de cadena con formato: 0,01

Por lo tanto, parecería que el método decimal.TryParse tiene la culpa.

cosas que hemos probado:

  • desinstalar y reinstalar la aplicación cliente
  • desinstalación y reinstalación de .NET 3.5 SP1
  • Comparando la configuración regional de la máquina defectuosa para los números (utilizando Inglés (Reino Unido)) a los de una máquina en funcionamiento - sin diferencias.

¿Alguien ha visto algo como esto o tiene alguna sugerencia? Rápidamente me estoy quedando sin ideas ...


Mientras estaba escribiendo esto un poco más de información se produjo en: Pasar un valor de cadena de "10000" para convertir.ToInt32() devuelve 0, por lo que también parece caer las principales 1.


Otras pruebas basadas en los comentarios:

  • 1,01 -> 0,01
  • 111.01 -> 11,01
  • 123.01 -> 23,01
  • 231,01 -> 231,01
  • 01,01 -> 1,01

Parece que solo afecta a 1s y solo si son el primer caracter de la cadena. Muy extraño, pero al menos es consistente.

+1

extraño. ¿Qué sucede con otros dígitos como "123" o "321"? –

+0

¿Mala RAM en la máquina? ¿Has intentado ejecutar algo como memtest86? –

+0

Esta es una muy mala idea, pero si pre-almohadilla con un cero ...? – spender

Respuesta

16

Puedo reproducir sus resultados. Considere:

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

Y luego:

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

La cosa es: Configuración regional no le muestra el signo positivo actual , y sobre todo: no ha configurado la cultura al analizar el número .

El valor puede venir de varios lugares: Puede haber llegado desde el registro como los valores predeterminados del sistema, o los valores por defecto se podría haber configurado en el código:

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

Interesante respuesta, pero plantea la pregunta de que si Configuración regional no le permite establecer el signo positivo, y la configuración regional del OP es la misma que la de las otras máquinas, ¿cómo podría haberse cambiado el signo positivo? No estoy en desacuerdo contigo, encaja perfectamente con los ejemplos, solo tengo curiosidad. –

+2

¡Y tenemos un ganador! Simplemente ejecuté el siguiente código en su máquina: Console.WriteLine (System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PositiveSign); y emite "1". Ahora, solo necesito descubrir cómo cambiar esto de vuelta ... –

+0

Apuesto a que fue un programa de terceros que hizo esto. Que monstruosidad – Kugel

-1

ver cómo se configuran las configuraciones regionales para esta computadora, podría ser que "." se establece como separador de miles, no como separador decimal. Intente usar Decimal.TryParse (String, NumberStyles, IFormatProvider, out Decimal val) y pase NumberFormatInfo creado con el separador decimal "."

+2

OP ya ha dicho que no hay diferencias en la configuración regional; más si se ingresó 1,000 cuando '.' era un separador de mil, daría 1000, no 0. –

Cuestiones relacionadas