在我们的应用程序中,我们有一个Money类型,其中包含金额(十进制)和货币代码(字符串)。以简单的形式,它看起来像这样:
public class Money
{
public decimal Amount{get;set;}
public string CurrencyCode{get;set;}
}
正如您可能想象的那样,它会在应用程序的许多位置使用,并且在发送到客户端或从客户端发送时经常被序列化/反序列化。货币金额通常被序列化为复合值,例如“1.23USD”代表1.23美元。旧客户端(HTML / JS)会将该值解析为其组件部分,返回Money类型。 Money值作为元素值发送,并作为属性值发送,具体取决于它们在应用程序中的位置,例如:
<SomeClass moneyValue="1.23USD" ... />
或
<SomeClass>
<MoneyValue>1.23USD</MoneyValue>
...
</SomeClass>
我试图找出一种方法,我可以使用内置的C#/。NET Xml序列化工具来实现同样的行为。我看过实现ISerializable,但是还没有找到正确的方法。
基本上,我希望能够通过我自己的自定义逻辑(知道如何将“1.23USD”解析为Money金额)来反序列化Money金额,并将其序列化为简单的字符串,例如: “1.23USD”
最终目标是能够将课程中的金额作为:
[XmlAttribute]
public Money SomeField // SomeField='123.USD
或:
[XmlElement]
public Money SomeOtherField //<SomeOtherField>1.23USD</SomeOtherField>
就像使用int,string,double等简单类型一样。
这可能吗?
答案 0 :(得分:3)
原来确实没有一个很好的100%答案 - 问题是你不能将复杂类型(例如Money)序列化为属性,即使你将它序列化为一个简单的字符串。所以无论如何,我都不能拥有一些可以在一般方面重复使用的属性='1.23美元'。
所以...发布的答案是属性的一个很好的解决方法,对于我使用Money作为元素的地方,我只是实现了IXmlSerializable来输出复合字段并在解析时重新拆分它。这样,不需要包装器,它只是工作。
public struct Money : IXmlSerializable
{
public double Amount { get; set; }
public string CurrencyCode { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
return (null);
}
public void ReadXml(System.Xml.XmlReader reader)
{
reader.MoveToContent();
Boolean isEmptyElement = reader.IsEmptyElement; // (1)
reader.ReadStartElement();
if (!isEmptyElement) // (1)
{
var str = reader.ReadContentAsString();
string[] sa = str.Split(' ');
Amount = double.Parse(sa[0]);
CurrencyCode = sa[1];
reader.ReadEndElement();
}
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteString(Amount + " " + CurrencyCode);
}
}
对于属性,发布的答案也可以,谢谢。
答案 1 :(得分:1)
以下代码可以解决问题:
public class Money
{
public decimal Amount { get; set; }
public string CurrencyCode { get; set; }
}
public class SomeClass
{
public SomeClass() { }
[XmlIgnore]
public Money WrappedMoney { get; set; }
[XmlAttribute]
public string moneyValue
{
get
{
return String.Format("{0:.##}{1}", WrappedMoney.Amount, WrappedMoney.CurrencyCode);
}
}
}
public class ParentClass
{
public SomeClass SomeClass {get; set;}
}
class Program
{
public static int Main(string[] args)
{
var parent = new ParentClass
{
SomeClass = new SomeClass
{
WrappedMoney = new Money { Amount = 1.25M, CurrencyCode = "USD" }
}
};
var serializer = new XmlSerializer(typeof(ParentClass));
using (var writer = new StreamWriter("output.xml"))
{
serializer.Serialize(writer, parent);
}
return 0;
}
}
Xml输出是:
<?xml version="1.0" encoding="utf-8"?>
<ParentClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SomeClass moneyValue="1.25USD" />
</ParentClass>