使用DataContractJsonSerializer进行序列化后,为什么数组显示为null?

时间:2015-11-18 15:49:17

标签: c# json xml xmlserializer datacontractjsonserializer

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

我将XML字符串转换为JSON字符串,方法是将XML反序列化为DataContract对象,然后使用DataContractJsonSerializer将该对象序列化为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
    }
  ]
}

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

我需要在对象模型上更改什么才能正确转换数组?

1 个答案:

答案 0 :(得分: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将成功反序列化。