由于格式化,XML反序列化在十进制解析时崩溃
当我尝试将XML解析为对象时,我得到一个System.FormatException。 据我所知,这是由于System.Xml.Serialization.XmlSerializer.Deserialize中使用的文化,期望一个点作为十进制字符,但xml包含一个逗号。
该对象如下所示:
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; } }
xml:
2013-07-02 -459,00 description 1
2013-07-02 -459,00 description 1
我通过引入第二个使用我自己的文化解析第一个属性来实现它:
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; } } }
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; } } }
这暴露了我不想要的额外财产。
所以我的问题是:有没有另一种方法可以做到这一点,没有遍历每个元素并解析/手动“分配”到对象?
XML序列化程序使用标准化的Number和DateTime格式,该标准在W3C架构数据类型规范https://www.w3.org/TR/xmlschema-2/中定义。
不要指望XmlSerializer
关注线程的CultureInfo
,它有意使用标准化格式来确保您可以独立于文化/区域设置序列化/反序列化。
你可以做的是有一个属性,用于序列化/反序列化decimal
。
请参阅: 将XML部分反序列化为Object
[XmlType("transaction")] public sealed class Transaction { [XmlElement("transactionDate")] public DateTime TransactionDate { get; set; } [XmlIgnore] public decimal Amount { get; set; } [XmlElement("transactionAmount")] [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public string AmountSerialized { get { return Amount.ToString(CultureInfo.CreateSpecificCulture("sv-SE")); } set { decimal amount; Decimal.TryParse(value, NumberStyles.Any, CultureInfo.CreateSpecificCulture("sv-SE"), out amount); Amount = amount; } } [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; } }
这样您就可以获取/设置Amount
而无需担心它是如何序列化的。 由于这是一个DTO,你可以创建另一个没有AmountSerialized
作为你的域对象的类(并使用类似AutoMapper的东西来使转换无痛)。
用法:
var data = @" 2013-07-02 -459,00 description 1 "; var serializer = new XmlSerializer(typeof(Transaction)); using(var stream = new StringReader(data)) using(var reader = XmlReader.Create(stream)) { Console.Write(serializer.Deserialize(reader)); }
在transactionDate
的结束标记中也有一个拼写错误。
如果您了解生成XML的文化,一个简单的解决方案是在反序列化之前将当前线程的文化切换到该文化。
上述就是C#学习教程:由于格式化,XML反序列化在十进制解析时崩溃分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
System.Globalization.CultureInfo oCurrentCulture = null; try { // Save the current culture oCurrentCulture = System.Threading.Thread.CurrentThread.CurrentCulture; System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de-DE"); // Do your work } finally { // Restore the saved culture System.Threading.Thread.CurrentThread.CurrentCulture = oCurrentCulture; }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1010381.html