Viene generata una eccezione System.FormatExwn quando provo ad analizzare XML in un oggetto. Per quanto posso dire, è dovuto alla cultura utilizzata in System.Xml.Serialization.XmlSerializer.Deserialize, che si aspetta un punto come carattere decimale, ma l'xml contiene una virgola.La deserializzazione XML si arresta in modo anomalo sull'analisi decimale a causa della formattazione
L'oggetto appare come segue:
public sealed class Transaction
{
[XmlElement("transactionDate")]
public DateTime TransactionDate { get; set; }
[XmlElement("transactionAmount")]
public decimal Amount { get; set; }
[XmlElement("transactionDescription")]
public string Description { get; set; }
[XmlElement("transactionType")]
public int Type { get; set; }
public static Transaction FromXmlString(string xmlString)
{
var reader = new StringReader(xmlString);
var serializer = new XmlSerializer(typeof(Transaction));
var instance = (Transaction) serializer.Deserialize(reader);
return instance;
}
}
Il xml:
<transaction>
<transactionDate> 2013-07-02 <transactionDate>
<transactionAmount>-459,00</transactionAmount>
<transactionDescription>description</transactionDescription>
<transactionType>1</transactionType>
</transaction>
Ho fatto funzionare con l'introduzione di una seconda proprietà che analizza il primo utilizzo la mia cultura:
namespace MyNamespace
{
[XmlRoot("transaction"), XmlType("Transaction")]
public sealed class Transaction
{
[XmlElement("transactionDate")]
public DateTime TransactionDate { get; set; }
[XmlElement("transactionAmount")]
public string Amount { get; set; }
public decimal AmountAsDecimal {
get
{
decimal value;
Decimal.TryParse(Amount, NumberStyles.Any, CultureInfo.CreateSpecificCulture("sv-SE"), out value);
return value;
}
}
[XmlElement("transactionDescription")]
public string Description { get; set; }
[XmlElement("transactionType")]
public int Type { get; set; }
public static Transaction FromXmlString(string xmlString)
{
var reader = new StringReader(xmlString);
var serializer = new XmlSerializer(typeof(Transaction));
var instance = (Transaction) serializer.Deserialize(reader);
return instance;
}
}
}
che espone una proprietà extra t cappello non voglio lì.
Quindi la mia domanda è: c'è un altro modo per farlo, senza iterare su ogni elemento e analizzarlo/assegnarlo all'oggetto "manualmente"?
Da [qui] (http://forums.asp.net/t/1365779.aspx) sembra che XmlSerializer stia utilizzando [questo schema W3C] (http://www.w3.org/TR/xmlschema -2 /) e si suppone che sia relativamente indipendente dalla cultura per evitare problemi di serializzazione/deserializzazione su macchine/culture. Vorrei capire che quello che stai facendo ora è probabilmente il modo migliore (magari adornare 'AmountAsDecimal' con' [XmlIgnore] 'solo così è un po 'più ovvio). Indipendentemente da ciò, fintanto che i vostri oggetti serializzati sono puramente oggetti per il trasferimento dei dati e astratti dalla vostra applicazione/logica di business, non dovrebbe farmi troppo male, spero. –
Ma in seconda lettura, è possibile capovolgere quale proprietà analizza e quali serializza. Esporre 'Importo decimale pubblico' come valore che si otterrebbe/imposta normalmente nell'API _code_ ma che ha come '[XmlIgnore]'.Quindi disponi di una proprietà 'stringa seriale SerializedAmount' le cui implementazioni get/set formatteranno/analizzeranno la tua cultura specializzata. Almeno in questo modo l'API che usi per _write_ l'oggetto 'Transaction' non deve pensare a come formattare la stringa; scrive solo un valore 'decimale'. Se il modo in cui lo scrivi (ad esempio modifichi la proprietà 'SerializedAmount'), il tuo codice non interessa. –