Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject

I have a valid json (any json string) string and trying to convert it to Dataset but Newtonsoft.Json failed to do so.

Json text:

  {"root": {
  "Item": [
    {
      "Name": "Super Mario Bros",
      "Count": "14",
      "Price": "29,99",
      "Comment": "-No Comment-",
      "Artist": "N/A",
      "Publisher": "Nintendo",
      "Genre": "Video Games",
      "Year": "1985",
      "ProductID": "001"
    },
    {
      "Name": "The Legend of Zelda",
      "Count": "12",
      "Price": "34,99",
      "Comment": "-No Comment-",
      "Artist": "N/A",
      "Publisher": "Nintendo",
      "Genre": "Video Games",
      "Year": "1986",
      "ProductID": "002"
    }
  ]
}
}

Code:

var table = JsonConvert.DeserializeObject<DataSet>(jsonText);

Error:

Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject. Path 'root', line 1, position 9.

Edit 1:

user can pass any type of json and i need to convert it to DataSet for the above example "root" element can contain any other property like "child1":"val1", "child2":"val2" and so forth. so, the output dataset will contain 2 tables namse root(should have one rows of properties 1 and 2) and item(should have 2 rows of type name,count,price etc).

2 answers

  • answered 2018-01-11 19:48 Alexander Petrov

    The Json you showed is invalid.

    It should look like this, to be load to the DataSet:

    {
      "Item": [
        {
          "Name": "Super Mario Bros",
          "Count": "14",
          "Price": "29,99",
          "Comment": "-No Comment-",
          "Artist": "N/A",
          "Publisher": "Nintendo",
          "Genre": "Video Games",
          "Year": "1985",
          "ProductID": "001"
        },
        {
          "Name": "The Legend of Zelda",
          "Count": "12",
          "Price": "34,99",
          "Comment": "-No Comment-",
          "Artist": "N/A",
          "Publisher": "Nintendo",
          "Genre": "Video Games",
          "Year": "1986",
          "ProductID": "002"
        }
      ]
    }
    

    Code:

    var dataSet = JsonConvert.DeserializeObject<DataSet>(jsonText);
    var table = dataSet.Tables[0];
    

  • answered 2018-01-11 19:48 Brian Rogers

    It is not working because the JSON object representing the DataSet is not at the root level of the JSON. In your JSON, it is inside a property called root, which is inside another wrapper object. So you will need to take that outer object into account when you deserialize. You can either define a wrapper class and deserialize into that:

    public class Wrapper
    {
        [JsonProperty("root")]
        public DataSet DataSet { get; set; }
    }
    

    Then:

    DataSet ds = JsonConvert.DeserializeObject<Wrapper>(json).DataSet;
    

    (Fiddle)

    Or, if you don't want to make a class, you can instead deserialize into a JObject, navigate down to the root property and then materialize it to a DataSet from there:

    DataSet ds = JObject.Parse(json)["root"].ToObject<DataSet>();
    

    (Fiddle)