XmlSerializer不会序列化派生值
(代码示例基于.NET 8)
我有一个 XmlSerializer,它应该给出一个小数的格式化版本(仅保留两位小数)。但当我运行这里显示的代码时,字段 IAmString 和 IAmAlsoString 被完全忽略。为了完整起见:在 ToString() 中移除 "c2" 并不会改变结果。
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApp3;
[XmlRoot(Namespace = "urn:iso:std:iso:20022:tech:xsd:pain.008.001.08")]
public class DecimalTestCase
{
[XmlElement("IAmDecimal")]
public decimal Value { get; set; }
[XmlElement("IAmString")]
public string AmountAsString => Value.ToString("c2");
[XmlElement("IAmAlsoString")]
public string AnotherTry
{
get
{
return Value.ToString("c2");
}
}
}
public class Run
{
public static void Main()
{
SerializeObject("DecimalToString.xml");
}
public static void SerializeObject(string filename)
{
XmlSerializer mySerializer = new(typeof(DecimalTestCase));
TextWriter writer = new StreamWriter(filename);
DecimalTestCase myDecimalTestCase = new()
{
Value = 123.1234m
};
mySerializer.Serialize(writer, myDecimalTestCase);
writer.Close();
}
}
我得到的结果是:
<?xml version="1.0" encoding="utf-8"?>
<DecimalTestCase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.08">
<IAmDecimal>123.1234</IAmDecimal>
</DecimalTestCase>
现在我已经完全不知道该尝试什么。甚至连弄清楚序列化器为何忽略这两个输出的逻辑都不知道。
这真的就是确保小数只输出两位的正确做法吗?还是有更好的办法?
解决方案
原因是这些属性是只读的。
来自 https://learn.microsoft.com/en-us/dotnet/standard/serialization/introducing-xml-serialization:
XML序列化不会转换方法、索引器、私有字段,或只读属性(除了只读集合)。要序列化对象的所有字段和属性(包括公有和私有的),请改用DataContractSerializer而不是XML序列化。
如果你为第二个属性添加一个抛出异常的setter,例如
[XmlElement("IAmAlsoString")]
public string AnotherTry
{
get => Value.ToString("c2");
set => throw new InvalidOperationException();
}
那么 IAmAlsoString 会被包含在输出中。
就个人而言,我从来不是 XmlSerializer 的铁粉——使用LINQ to XML时,编写自定义序列化/反序列化代码其实相当直接,这样你就不需要担心像这样的怪异之处。诚然,我也从来没有需要对一大批类型这么做过——但如果你只有相对较少的类型,编写 FromXElement 静态方法和 ToXElement 实例方法其实也相当直接,并且它会让你获得完全的控制。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。