0

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..

0 Answers0