问题
This seems to be the same question as below but that answer hasn't resolved it:
Deserializing a Simple JSON Array
I am using DataContractJsonSerializer to convert from XML to JSON and vice versa. Everything works with complex data types and arrays of complex data types but I'm having a problem producing JSON for a string array.
The JSON I need to produce should have this structure:
{
"data": {
"x_axis": {
"labels": [ "Jan", "Feb", "Mar", "Apr","May", "Jun", "Jul", Aug","Sep", Oct", "Nov", "Dec" ]
}
}
}
The objects I am using are:-
LineChartData:
[DataContract]
public class LineChartData
{
[DataMember(Name = "x_axis")]
public LineChartXAxis XAxis { get; set; }
}
LineChartXAxis:
[DataContract]
public class LineChartXAxis
{
[DataMember(Name = "labels")]
public string[] Labels { get; set; }
}
The XML I am trying to convert looks like this:
<LineChartData>
<XAxis>
<Labels>Jan</Labels>
<Labels>Feb</Labels>
<Labels>Mar</Labels>
<Labels>Apr</Labels>
<Labels>May</Labels>
<Labels>Jun</Labels>
<Labels>Jul</Labels>
<Labels>Aug</Labels>
<Labels>Sep</Labels>
<Labels>Oct</Labels>
<Labels>Nov</Labels>
<Labels>Dec</Labels>
</XAxis>
</LineChartData>
My deserialising code is:
var serialiser = new XmlSerializer(typeof(LineChartData));
var stringReader = new StringReader(xml);
var result = serialiser.Deserialize(stringReader);
The JSON I get back always has an empty labels array:
{
"data": {
"x_axis": {
"labels":[]
}
}
}
How should I be defining the Labels property in LineChartXAxis to serialise the JSON correctly?
回答1:
You have a couple issues here:
Your
<Labels>
collection does not have an outer container element. By defaultXmlSerializer
adds a container element when serializing a collection. To skip the outer wrapper element, add an[XmlElement("Labels")]
attribute to theLabels
property. (XML serializer attributes and data contract attributes are mutually independent and may both be applied without one set affecting the other.)I.e. your actual problem is in reading your list of strings from XML not writing then to JSON.
Your JSON has an outer root element corresponding to the
{"data": {...}}
object. You need to account for this when serializing. (Maybe you do and this is not shown.)
Thus the following should work:
[DataContract]
public class LineChartData
{
[DataMember(Name = "x_axis")]
public LineChartXAxis XAxis { get; set; }
}
[DataContract]
public class LineChartXAxis
{
[DataMember(Name = "labels")]
[XmlElement("Labels")]
public string[] Labels { get; set; }
}
[DataContract]
public class RootObject<T>
{
[DataMember(Name = "data")]
public T Data { get; set; }
}
public static class RootObjectExtensions
{
public static RootObject<T> FromData<T>(T data)
{
return new RootObject<T> { Data = data };
}
}
And then use them like
var data = xmlString.LoadFromXML<LineChartData>();
var jsonString = DataContractJsonSerializerHelper.GetJson(RootObjectExtensions.FromData(data));
With extension methods:
public static class XmlSerializerHelper
{
public static T LoadFromXML<T>(this string xmlString, XmlSerializer serial = null)
{
using (StringReader reader = new StringReader(xmlString))
{
object result = (serial ?? new XmlSerializer(typeof(T))).Deserialize(reader);
if (result is T)
return (T)result;
}
return default(T);
}
}
public static class DataContractJsonSerializerHelper
{
public static string GetJson<T>(T obj, DataContractJsonSerializer serializer = null)
{
using (var memory = new MemoryStream())
{
(serializer ?? new DataContractJsonSerializer(typeof(T))).WriteObject(memory, obj);
memory.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(memory))
{
return reader.ReadToEnd();
}
}
}
}
Incidentally, as an alternative, you could look at Json.NET, which has the ability to convert directly between JSON and XML.
回答2:
Traditional arrays are not easily resized and I think that is the reason the serializer is having issues. Change your Labels
property to be a List<string>
instead and that should work.
来源:https://stackoverflow.com/questions/31994606/how-can-i-serialise-a-string-array-to-json-using-datacontractjsonserializer