基类和继承类的 XML 序列化信息
Posted
技术标签:
【中文标题】基类和继承类的 XML 序列化信息【英文标题】:XML Serializing information on Base class and inherited class 【发布时间】:2020-04-16 20:24:51 【问题描述】:我正在尝试将 C# 对象序列化为 XML,以便它可以用作 API 调用的主体。他们对所需的输入非常挑剔。我已经构建了以下类来保存我需要发送给他们的数据。包括属性和所有属性作为元素而不是属性。他们还要求列表包含type="array"
,尽管创建我自己的类来实现 List 是最简单的,因为我给它们的所有列表都必须具有相同的属性。当发生序列化时,它会序列化 List 项的基类,但它不包括我想要的派生类的属性。
public class CustomArray<T> : List<T>
[XmlAttribute]
public string type get; set; = "array";
[XmlRoot("message")]
public class MessageBody
[XmlArray("Checks"), XmlArrayItem("CheckItem")]
public CustomArray<Check> CheckList get; set;
public class Check
[XmlElement("C_CHECK_NUMBER")]
public string CheckNumber get; set;
[XmlElement("C_CHECK_AMOUNT")]
public decimal Amount get; set;
[XmlArray("InvoiceList"), XmlArrayItem("Invoice")]
public CustomArray<Invoice> InvoiceList get; set;
public class Invoice
[XmlElement("C_INVOICE_ID")]
public long ID get; set;
[XmlElement("C_INVOICE_NUM")]
public string InvoiceNum get; set;
然后我运行这段代码:
// Create a sample object
var message = new MessageBody()
CheckList = new CustomArray<Check>
new Check
CheckNumber = "111",
Amount = 1.00M
,
new Check
CheckNumber = "112",
Amount = 2.00M,
InvoiceList = new CustomArray<Invoice>
new Invoice
ID = 1,
InvoiceNum = "1"
;
// Create custom settings
var settings = new XmlWriterSettings
OmitXmlDeclaration = true,
Indent = true
;
// Serialize item and print it to console
using (var sw = new StringWriter())
using (var writer = XmlWriter.Create(sw, settings))
var serializer = new XmlSerializer(message.GetType());
serializer.Serialize(writer, message, new XmlSerializerNamespaces(new[] XmlQualifiedName.Empty ));
Console.WriteLine(sw.ToString());
我把这个写到控制台:
<message>
<Checks>
<CheckItem>
<C_CHECK_NUMBER>111</C_CHECK_NUMBER>
<C_CHECK_AMOUNT>1.00</C_CHECK_AMOUNT>
</CheckItem>
<CheckItem>
<C_CHECK_NUMBER>112</C_CHECK_NUMBER>
<C_CHECK_AMOUNT>2.00</C_CHECK_AMOUNT>
<InvoiceList>
<Invoice>
<C_INVOICE_ID>1</C_INVOICE_ID>
<C_INVOICE_NUM>1</C_INVOICE_NUM>
</Invoice>
</InvoiceList>
</CheckItem>
</Checks>
</message>
但我需要得到这个:
<message>
<Checks type="array">
<CheckItem>
<C_CHECK_NUMBER>111</C_CHECK_NUMBER>
<C_CHECK_AMOUNT>1.00</C_CHECK_AMOUNT>
</CheckItem>
<CheckItem>
<C_CHECK_NUMBER>112</C_CHECK_NUMBER>
<C_CHECK_AMOUNT>2.00</C_CHECK_AMOUNT>
<InvoiceList type="array">
<Invoice>
<C_INVOICE_ID>1</C_INVOICE_ID>
<C_INVOICE_NUM>1</C_INVOICE_NUM>
</Invoice>
</InvoiceList>
</CheckItem>
</Checks>
</message>
感谢您的帮助!
这是我为了炫耀而制作的 dotnetfiddle。这并不准确,但它具有相同的想法。 https://dotnetfiddle.net/ALCX5H
【问题讨论】:
【参考方案1】:尝试以下:
[XmlRoot("message")]
public class MessageBody
[XmlElement("Checks")]
public Checks Checks get; set;
public class Checks
[XmlAttribute]
public string type get; set;
[XmlElement("Checks")]
public List<Check> Checks get; set;
public class Check
[XmlElement("C_CHECK_NUMBER")]
public string CheckNumber get; set;
[XmlElement("C_CHECK_AMOUNT")]
public decimal Amount get; set;
【讨论】:
这会起作用,但它需要我为用于此 API 的每个列表创建一个新类。我有另一个嵌入在 Check 类中的列表,我希望每次都使用一个通用类。我感觉在完成更多测试后这是不可能的,因为序列化程序正在查看属性以查看它是否实现了 IEnemurable 和泛型,如果实现了,它开始序列化泛型项并且不关心其他任何项自定义列表类的属性。 @JDB - 你必须描述/举例说明那个额外的“列表”是什么。根据此,可以调整/扩展上述内容。 在一个检查项目中,我也可能有一个List<Invoice>
。通过上述实现,我还必须有一个用于包装 Invoices 的类。我希望我可以有一个通用的特殊列表类,我可以在需要列表的任何时候调用它。让它工作并非不可能,它只是不是最干净的解决方案。我担心它可能是唯一的解决方案,所以我可以让它工作。我将用另一个场景编辑原始问题。以上是关于基类和继承类的 XML 序列化信息的主要内容,如果未能解决你的问题,请参考以下文章