为什么在使用 DataContractJsonSerializer 序列化后数组显示为 null?
Why are arrays being shown as null after serializing using DataContractJsonSerializer?
有很多关于使用 DataContractJsonSerializer 序列化和反序列化数组的问题(包括我提出的一个问题:),但 none 似乎回答了我当前遇到的问题。
我正在将 XML 字符串转换为 JSON 字符串,方法是使用 DataContractJsonSerializer 将 XML 反序列化为 DataContract 对象,然后将该对象序列化为 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;
}
}
当我测试它时,结果 JSON 中的 Consignments 属性 始终为 null。
"order": {
"consignments": [
{
"conh_id": null,
"conh_status": null,
"consignmententries": null
}
]
}
调试显示在反序列化步骤后创建的对象中此 属性 为空,因此问题出在 XML 反序列化而不是 JSON 序列化。
我需要对我的对象模型进行哪些更改才能正确转换数组?
当您从 XML 反序列化而不是序列化到 JSON 时,您的问题就会发生。在您的 XML 中,集合已序列化为两个级别:外部容器元素和每个项目的元素:
<consignments>
<consignment>
<!-- Consignment data -->
</consignment>
</consignments>
和
<consignmententries>
<consignmententry>
<!-- Entry data -->
</consignmententry>
</consignmententries>
(为了比较,在 the Labels
XML collection has a single level). Thus you need to use [XmlArray(string name)]
and [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
集合应该在没有外部容器元素的情况下进行序列化。
您还需要在 Order
中添加 [XmlRoot("order")]
以指定根元素名称。
现在您的 XML 将成功反序列化。
有很多关于使用 DataContractJsonSerializer 序列化和反序列化数组的问题(包括我提出的一个问题:
我正在将 XML 字符串转换为 JSON 字符串,方法是使用 DataContractJsonSerializer 将 XML 反序列化为 DataContract 对象,然后将该对象序列化为 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;
}
}
当我测试它时,结果 JSON 中的 Consignments 属性 始终为 null。
"order": {
"consignments": [
{
"conh_id": null,
"conh_status": null,
"consignmententries": null
}
]
}
调试显示在反序列化步骤后创建的对象中此 属性 为空,因此问题出在 XML 反序列化而不是 JSON 序列化。
我需要对我的对象模型进行哪些更改才能正确转换数组?
当您从 XML 反序列化而不是序列化到 JSON 时,您的问题就会发生。在您的 XML 中,集合已序列化为两个级别:外部容器元素和每个项目的元素:
<consignments>
<consignment>
<!-- Consignment data -->
</consignment>
</consignments>
和
<consignmententries>
<consignmententry>
<!-- Entry data -->
</consignmententry>
</consignmententries>
(为了比较,在Labels
XML collection has a single level). Thus you need to use [XmlArray(string name)]
and [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
集合应该在没有外部容器元素的情况下进行序列化。
您还需要在 Order
中添加 [XmlRoot("order")]
以指定根元素名称。
现在您的 XML 将成功反序列化。