【发布时间】:2013-07-03 00:33:58
【问题描述】:
当我尝试将 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:
<transaction>
<transactionDate> 2013-07-02 <transactionDate>
<transactionAmount>-459,00</transactionAmount>
<transactionDescription>description</transactionDescription>
<transactionType>1</transactionType>
</transaction>
我通过引入第二个属性来实现它,该属性使用我自己的文化解析第一个属性:
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;
}
}
}
它暴露了一个我不想要的额外属性。
所以我的问题是:是否有另一种方法可以做到这一点,而无需迭代每个元素并“手动”解析/分配给对象?
【问题讨论】:
-
来自here 听起来XmlSerializer 正在使用this W3C schema 并且应该相对独立于文化以避免跨机器/文化的序列化/反序列化问题。我会猜你现在正在做的可能是最好的方式(也许用
[XmlIgnore]装饰AmountAsDecimal只是让它更明显一点)。无论如何,只要您的序列化对象是纯粹的数据传输对象并从您的应用程序/业务逻辑中抽象出来,那么我希望它不会造成太大伤害。 -
但在第二次阅读时,您可能想要翻转哪些属性解析和哪些序列化。将
public decimal Amount公开为您将在代码 API 中正常获取/设置的值,但将其作为[XmlIgnore]。然后有一个public string SerializedAmount属性,其 get/set 实现将格式化/解析您的专业文化。至少这样,您用于写入Transaction对象的 API 不必考虑如何格式化字符串;它只是写入一个decimal值。如果您编写它的方式(例如您更改SerializedAmount属性),那么您的代码并不关心。
标签: c# .net xml serialization xml-deserialization