I'm handling XML data coming in, the "top" of the data is fixed, the "rows" within may vary in content and quantity.
My code works when deserializing to JSON then to a data table, but if the number of rows is 1, it fails. I get this error message:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'DynamicJSON.DynamicJSON+Row[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
I'm probably missing something really obvious, but haven't been able to find an answer yet.
I've tried the solution in this post but end up with a stack overflow error (somewhat ironic...) Handling JSON single object and array
My code for handling the original xml:
XmlDocument doc = new XmlDocument();
doc.LoadXml(File.ReadAllText("C:\\temp\\file.xml").ToString());
string json = JsonConvert.SerializeXmlNode(doc);
DynamicJSON.Rootobject r = JsonConvert.DeserializeObject<DynamicJSON.Rootobject>(json);
JObject jObject = JObject.Parse(json);
JArray jArray = (JArray)jObject["SOAP-ENV:Envelope"]["SOAP-ENV:Body"]["reportresponse"]["row"];
DataTable jdt = (DataTable)JsonConvert.DeserializeObject(jArray.ToString(), (typeof(DataTable)));
My Class
class DynamicJSON
{
public class Rootobject
{
[JsonProperty("SOAP-ENV:Envelope")]
public SOAPENVEnvelope SOAPENVEnvelope { get; set; }
}
public class SOAPENVEnvelope
{
public string xmlnsSOAPENV { get; set; }
public string xmlnsSOAPENC { get; set; }
public string xmlnsxsi { get; set; }
public string xmlnsxsd { get; set; }
[JsonProperty("SOAP-ENV:Header")]
public SOAPENVHeader SOAPENVHeader { get; set; }
[JsonProperty("SOAP-ENV:Body")]
public SOAPENVBody SOAPENVBody { get; set; }
}
public class SOAPENVHeader
{
public string reportname { get; set; }
public string reportstartdate { get; set; }
public string reportenddate { get; set; }
public string reportmerchantid { get; set; }
}
public class SOAPENVBody
{
public Reportresponse reportresponse { get; set; }
[JsonProperty("SOAP-ENV:Fault")]
public SOAPENVFault? SOAPENVFault { get; set; }
}
public class SOAPENVFault
{
public string faultcode { get; set; }
public string faultstring { get; set; }
}
[JsonConverter(typeof(SingleOrArrayConverter<Row>))]
public class Reportresponse
{
public Row[] row { get; set; }
}
public class Row
{
[JsonExtensionData]
public Dictionary<string, JToken> child { get; set; }
public Row()
{
child = new Dictionary<string, JToken>();
}
}
}
My XML looks like this:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Header>
<reportname>ReportName</reportname>
<reportstartdate>2020-Jun-1</reportstartdate>
<reportenddate>2020-Jun-1</reportenddate>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<reportresponse>
<row>
<rowid>1</rowid>
<value1>1</value1>
<value2>1</value2>
<value3>1</value3>
</row>
</reportresponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The JSON is converted to this (as a single "row")
{
"SOAP-ENV:Envelope": {
"@xmlns:SOAP-ENV": "http://schemas.xmlsoap.org/soap/envelope/",
"@xmlns:SOAP-ENC": "http://schemas.xmlsoap.org/soap/encoding/",
"@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"@xmlns:xsd": "http://www.w3.org/2001/XMLSchema",
"SOAP-ENV:Header": {
"reportname": "ReportName",
"reportstartdate": "2020-Jun-1",
"reportenddate": "2020-Jun-1"
},
"SOAP-ENV:Body": {
"reportresponse": {
"row": {
"rowid": "1",
"value1": "1",
"value2": "1",
"value3": "1"
}
}
}
}
}
JSON array:
{
"SOAP-ENV:Envelope": {
"@xmlns:SOAP-ENV": "http://schemas.xmlsoap.org/soap/envelope/",
"@xmlns:SOAP-ENC": "http://schemas.xmlsoap.org/soap/encoding/",
"@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"@xmlns:xsd": "http://www.w3.org/2001/XMLSchema",
"SOAP-ENV:Header": {
"reportname": "ReportName",
"reportstartdate": "2020-Jun-1",
"reportenddate": "2020-Jun-1"
},
"SOAP-ENV:Body": {
"reportresponse": {
"row": [
{
"rowid": "1",
"value1": "1",
"value2": "1",
"value3": "1"
},
{
"rowid": "2",
"value1": "2",
"value2": "2",
"value3": "2"
}
]
}
}
}
}
I've tried without the SingleOrArrayConverter, I've also tried using dynamic and string instead of SingleOrArrayConverter<Row>
as well but so far no luck.
Appreciate anyone (politely) telling me where I'm missing the obvious..