7

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

A_Sk
  • 4,532
  • 3
  • 27
  • 51

3 Answers3

9

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)

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
  • what we will do in case of third party json?, if we do not know `json's first node name`, "root", in this example.... –  Oct 28 '21 at 12:21
  • 1
    @biryaz If you don't know the name of the first node, you can do this instead: `DataSet ds = JObject.Parse(json).Properties().First().Value.ToObject();` [Fiddle](https://dotnetfiddle.net/u3BDpV) – Brian Rogers Oct 29 '21 at 01:17
  • thanks, joining this with the answer of @dbc `https://stackoverflow.com/questions/48786123/xmlnodeconverter-can-only-convert-json-that-begins-with-an-object` did the trick –  Oct 29 '21 at 06:17
3

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];
Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49
  • json is valid, actually the json is dynamic in my case so user can load any type of json. root can have any other property as well apart from the item array. how can i deal with the situation like this. – A_Sk Jan 11 '18 at 20:26
  • @A_Name_Does_Not_Matter - Your json is invalid. It cannot start with literal. See [JSON](https://www.json.org/). Use any validator online to test. – Alexander Petrov Jan 11 '18 at 20:34
  • @A_Name_Does_Not_Matter - _any type_? Well, wait for the artificial intelligence. Or write your own logic to handle such situations. – Alexander Petrov Jan 11 '18 at 20:36
  • yes, json missing syntax but should contain the "root" node, updating question for more clarification. – A_Sk Jan 11 '18 at 20:39
  • Why was this answer selected as the solution? It doesn't solve the issue. – tpartee Jan 29 '20 at 22:16
0

just add [] while stringifying the object:

JSON.stringify([this.YourModel])
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Rahul
  • 1