SSudor
SSudor

Reputation: 107

Deserialize JSON with an array into DataTable?

I know this question is very popular here in StackOverflow, yet I can't seem to find a suitable solution... I've looked at pretty much every question related to this, tried almost every method, but none of them worked...

As it seems, my problem is that I have arrays inside my JSON and the JSON.Net deserializer doesn't like that at all. So, my last option is to post a question myself.

Here is my JSON:

{"artists":
  [
     {"Name":"artsit",
     "URL":"www.example.com",
     "Desc":"very nice artist",
     "Rating":5,
     "NSFW":false,
     "Tags":["good","epic"],
     "fav":true
    }, 
    {"Name":"another artist",
     "URL":"www.test.net",
     "Desc":"super cool",
     "Rating":3,
     "NSFW":true,
     "Tags":["digital","commissions"],
     "fav":false
     }
  ]
}

And here is my C# code:

using StreamReader r = new StreamReader("C:\\path\\to\\json\\file.json");
string json = r.ReadToEnd();
DataTable dt = JsonConvert.DeserializeObject<DataTable>(json);

But when I try to run it, I get the following exception:

Newtonsoft.Json.JsonSerializationException: 'Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject. Path '', line 1, position 1.'

In this particular question, there is an answer trying to fix this same issue I'm having, but I wasn't able to make it work, unfortunately.

Believe me, I have tried everything that looked suitable for this problem and I still cannot solve it, please help. I won't include the code I used for other solutions to this problem, like deserializing it to a custom class, because it would make everything even more confusing. I am using Visual Studio 2022, .NET 6.0 in a WinForms project.

Upvotes: 4

Views: 11402

Answers (3)

Idan
Idan

Reputation: 135

Did you try extracting the list from the outer dictionary?

dynamic jsonDict = JsonConvert.DeserializeObject(jsonString);
var jarrayString = JsonConvert.SerializeObject(jsonDict["artists"]);
var dt = JsonConvert.DeserializeObject<DataTable>(jarrayString);

This works because the object that you convert into a datatable needs to be an array. In your code, you used a dictionary, and the JSON library doesn't know what you want to do with it. A dictionary can contain many arrays and other elements. You need to extract the array from the dictionary, and then convert it to datatable.

Upvotes: 2

Charlieface
Charlieface

Reputation: 71193

Your problem is that the DataTable is actually a property of the root object, by the name of artists

So you could also create a class for the root object containing the DataTable.

class RootObject
{
    public DataTable artists;
}
var dt = JsonConvert.DeserializeObject<RootObject>(json).artists;

dotnetfiddle

Upvotes: 1

Serge
Serge

Reputation: 43860

You got an deserialize error "... Expected StartArray, got StartObject." So you can not to deserialize to DataTable the whole object , you need an array part only. An array part starts from "artists". So after parsing the whole object you have to deserilize "artists" part only.

try this. it was tested in Visual Studio

var jsonObject=JObject.Parse(json);
DataTable dt = jsonObject["artists"].ToObject<DataTable>();

Upvotes: 4

Related Questions