【问题标题】:Why are arrays being shown as null after serializing using DataContractJsonSerializer?为什么使用 DataContractJsonSerializer 序列化后数组显示为空?
【发布时间】:2015-11-18 15:49:16
【问题描述】:

有很多关于使用 DataContractJsonSerializer 序列化和反序列化数组的问题(包括我提出的一个问题:How can I serialise a string array to JSON using DataContractJsonSerializer?),但似乎没有一个能够回答我当前遇到的问题。

我通过将 XML 反序列化为 DataContract 对象,然后使用 DataContractJsonSerializer 将该对象序列化为 JSON,将 XML 字符串转换为 JSON 字符串。我的方法与我在许多其他对象上使用的方法相同,所有这些对象都完美地序列化为 JSON,但我有一个对象,其中数组属性在序列化后始终呈现为 null。

类定义如下:-

[DataContract]
public class Order
{
    [DataMember(Name = "consignments")]
    [XmlElement("consignments")]
    public Consignment[] Consignments { get; set; }
}

[DataContract]
public class Consignment
{
    [DataMember(Name = "conh_id")]
    [XmlElement("conh_id")]
    public string ConsignmentHeaderId { get; set; }

    [DataMember(Name = "conh_status")]
    [XmlElement("conh_status")]
    public string ConsignmentHeaderStatus { get; set; }

    [DataMember(Name = "consignmententries")]
    [XmlElement("consignmententries")]
    public ConsignmentEntry[] ConsignmentEntries { get; set; }
}

我使用的 XML 如下所示:-

<order>
  <consignments>
    <consignment>
      <conh_id>A19708176</conh_id>
      <conh_status>ACCEPTED</conh_status>
      <consignmententries>
        <consignmententry>
          <conl_lineNbr>10000</conl_lineNbr>
          <conl_sku>SEC01XXZBUXXX</conl_sku>
          <conl_original_qty>1</conl_original_qty>
        </consignmententry>
      </consignmententries>
    </consignment>
  </consignments>
</order>

反序列化和序列化通过以下方法完成:-

private object DeserialiseXml(string xml)
{
    var serialiser = new XmlSerializer(typeof(Order));
    var stringReader = new StringReader(xml);
    var result = serialiser.Deserialize(stringReader);

    return result;
}

private string SerialiseJson(object serialisable)
{
    using (MemoryStream stream = new MemoryStream())
    {
        var serialiser = new DataContractJsonSerializer(serialisable.GetType());
        serialiser.WriteObject(stream, serialisable);
        var json = Encoding.UTF8.GetString(stream.ToArray());

        return json;
    } 
}

当我对其进行测试时,Consignments 属性在生成的 JSON 中始终为 null。

"order": {
  "consignments": [
    {
      "conh_id": null,
      "conh_status": null,
      "consignmententries": null
    }
  ]
}

调试显示在反序列化步骤后创建的对象中该属性为空,因此问题出在 XML 反序列化而不是 JSON 序列化。

我需要对我的对象模型进行哪些更改才能正确转换数组?

【问题讨论】:

    标签: c# json xml xmlserializer datacontractjsonserializer


    【解决方案1】:

    当您从 XML 反序列化而不是序列化为 JSON 时,就会出现问题。在您的 XML 中,集合已按两个级别进行序列化:外部容器元素和每个项目的元素:

      <consignments>
        <consignment>
           <!-- Consignment data -->
        </consignment>
      </consignments>
    

      <consignmententries>
        <consignmententry>
           <!-- Entry data -->
        </consignmententry>
      </consignmententries>
    

    (为了比较,在linked question 中,Labels XML 集合只有一个级别)。因此,您需要使用[XmlArray(string name)][XmlArrayItem(string itemName)] 来指定外部和内部元素名称:

    [DataContract]
    [XmlRoot("order")]
    public class Order
    {
        [DataMember(Name = "consignments")]
        [XmlArray("consignments")]
        [XmlArrayItem("consignment")]
        public Consignment[] Consignments { get; set; }
    }
    
    [DataContract]
    public class Consignment
    {
        [DataMember(Name = "conh_id")]
        [XmlElement("conh_id")]
        public string ConsignmentHeaderId { get; set; }
    
        [DataMember(Name = "conh_status")]
        [XmlElement("conh_status")]
        public string ConsignmentHeaderStatus { get; set; }
    
        [DataMember(Name = "consignmententries")]
        [XmlArray("consignmententries")]
        [XmlArrayItem("consignmententry")]
        public ConsignmentEntry[] ConsignmentEntries { get; set; }
    }
    

    相反,将属性[XmlElement] 添加到集合中会告诉XmlSerializer 该集合应该在没有外部容器元素的情况下进行序列化。

    您还需要将[XmlRoot("order")] 添加到Order 以指定根元素名称。

    现在您的 XML 将成功反序列化。

    【讨论】:

    • dbc,效果很好。感谢您的答复。对于关注此问题的其他人,我遇到问题的原因是我的数组属性上的“[XMLElement]”属性。在其他对象模型中,我一直在序列化和反序列化 XML 元素名称与对象属性匹配,因此我不需要该属性。正是该属性导致数组的处理方式与我的预期不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    • 2013-08-13
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多