Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

json

c#

json.net

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

like image 266
A_Sk Avatar asked Jan 11 '18 19:01

A_Sk


2 Answers

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)

like image 110
Brian Rogers Avatar answered Oct 31 '22 10:10

Brian Rogers


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];
like image 44
Alexander Petrov Avatar answered Oct 31 '22 11:10

Alexander Petrov