Abbiate pazienza, non è mia abitudine lamentarmi, ma stavolta lo sbottare ci sta davvero tutto. Ma prima del fatto è bene che vi racconti l'antefatto. Stasera, io e il collega Andrea Dottor ci siamo scontrati con un comportamento apparentemente inspiegabile. Un pezzo di codice apparentemente perfetto falliva miseramente e inspiegabilmente. In buona sostanza quello che stavamo facendo era tutto sommato semplice; Un campo di tipo Textbox riceveva una stringa in che rappresentava una valuta, per la precisione "0,5" in seguito tale stringa arrivava al validatore serverside che utilizzando decimal.TryParse() verificava che si trattasse effettivamente di un decimal. Questo controllo, applicato sia con la CultureInfo che senza veniva eseguito perfettamente restituendo un chiaro e lampante "true". Tuttavia, pochi millisecondi dopo, quando la datasource tentava di mappare i campi su un oggetto di business, l'operazione miseramente scoppiava, con il seguente errore: "0,5" is not a valid value for Decimal.

Alla fine, solo analizzanto il codice del framework linea per linea con Reflector siamo giunti a capire il motivo per cui questa banale operazione scoppiava:

private static object ConvertType(object value, Type type, string paramName)
{
      
string text1 = value as string;

      
if (text1 != null)
      {
            TypeConverter converter1 = TypeDescriptor.GetConverter(type);

            
if (converter1 == null)
            {
                
return value;
            }
            
try
            
{
                
value = converter1.ConvertFromInvariantString(text1);
            }
            
catch (NotSupportedException)
            {
                
throw new InvalidOperationException(
                    SR.GetString("ObjectDataSourceView_CannotConvertType", 
                        
new object[] { paramName, typeof(string).FullName, type.FullName }));
            }
            
catch (FormatException)
            {
                
throw new InvalidOperationException(
                    SR.GetString("ObjectDataSourceView_CannotConvertType", 
                        
new object[] { paramName, typeof(string).FullName, type.FullName }));
            }
      }
      
return value;
}

Questo codice, estratto dalla classe ObjectDataSourceView è la causa del misfatto e precisamente la riga che chiama il metodo ConvertFromInvariantString() del TypeConverter. La ObjectDataSourceView, per inciso, è l'oggetto che all'interno della ObjectDataSource si incarica di effettuare le operazioni incapsulando al suo interno una rappresentazine dello storage. La chiamata a ConvertFromInvariantString() scritta in questo modo impone che un dato decimal, ma con tutta probabilità anche una data o un double, debba essere formattato con cultura neutra, e cioè nel nostro caso con il punto al posto della virgola. Una chiamata corretta sarebbe stata la seguente:

value = converter1.ConvertFromString(null, CultureInfo.CurrentCulture, text);

In questo modo la datasource avrebbe tenuto conto della cultura corrente e quindi si sarebbe adeguata al contesto del thread, consentendo alla conversione di avvenire correttamente. Ora, purtroppo i metodi in questione sono privati e perciò non è possibile porre rimedio a questo problema cercando di sostituire la ObjectDataSourceView con un oggetto che sia stato patchato. In realtà credo di avere un'idea per una soluzione, che però tenterò domattina, ma lasciatemi dire che un errore del genere non me lo sarei mai aspettato.

powered by IMHO 1.3

 


per leggere il post originale o inviare un commento visita il seguente indirizzo: ObjectDataSource e conversioni di tipi. Siamo certi che funziona?