【问题标题】:XML Serializing information on Base class and inherited class基类和继承类的 XML 序列化信息
【发布时间】: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

【问题讨论】:

    标签: c# xml serialization xml-serialization xmlserializer


    【解决方案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&lt;Invoice&gt;。通过上述实现,我还必须有一个用于包装 Invoices 的类。我希望我可以有一个通用的特殊列表类,我可以在需要列表的任何时候调用它。让它工作并非不可能,它只是不是最干净的解决方案。我担心它可能是唯一的解决方案,所以我可以让它工作。我将用另一个场景编辑原始问题。
    猜你喜欢
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 2010-12-15
    • 2011-05-23
    相关资源
    最近更新 更多