I'm relatively new to working with JSON and would like to deserialize content I downloaded from https://5e.tools/. I could try to anticipate all the tags/fields in a class, but the dataset example (https://www.newtonsoft.com/json/help/html/DeserializeDataSet.htm) looked more convenient so I tried that first:
using Newtonsoft.Json;
using System;
using System.Data;
using System.IO;
namespace _5EToolsConvertor
{
class Program
{
static void Main(string[] args)
{
string json = File.ReadAllText(@"D:\Downloads\5eTools.1.116.8\data\spells\spells-phb.json");
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(json);
DataTable dataTable = dataSet.Tables["spell"];
Console.WriteLine(dataTable.Rows.Count);
foreach (DataRow row in dataTable.Rows)
{
Console.WriteLine(row["name"] + " - " + row["level"]); // just to check
}
}
}
}
Here is part of the first item from the JSON file:
{"spell":[{"name":"Acid Splash","source":"PHB","page":211,"srd":true,"level":0,"school":"C","time":[{"number":1,"unit":"action"}],"range":{"type":"point","distance":{"type":"feet","amount":60}},"components":{"v":true,"s":true},"duration":[{"type":"instant"}], ...
I get the error:
An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
Unexpected JSON token when reading DataTable: StartObject. Path 'spell[0].range', line 1, position 139.
EDIT 11/30/2020
Advice in the comments suggested moving from a dataset model (spreadsheet) because some of my JSON fields are hierarchical. I've created a class with List<Jobject>
for the hierarchical fields like "Time". But, I'd rather end up with all data in vanilla c# objects like Dictionary<string, object>
. I'm having trouble converting. What is the best way? This code runs on the full JSON file but prints System.Collections.Generic.List
1[Newtonsoft.Json.Linq.JObject]` for every "Time" object.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
namespace _5EToolsConvertor
{
public class Spell
{
public string Name { get; set; }
public string Source { get; set; }
public string Page { get; set; }
public string SRD { get; set; }
public List<JObject> Time { get; set; }
}
class Program
{
static void Main(string[] args)
{
string jsontext = File.ReadAllText(@"D:\Downloads\5eTools.1.116.8\data\spells\spells-phb.json");
JObject json = JObject.Parse(jsontext);
// get JSON result objects into a list
IList<JToken> results = json["spell"].Children().ToList();
// serialize JSON results into .NET objects
IList<Spell> spells = new List<Spell>();
foreach (JToken item in results)
{
// JToken.ToObject is a helper method that uses JsonSerializer internally
Spell spell = item.ToObject<Spell>();
spells.Add(spell);
}
foreach (Spell spell in spells)
{
Console.WriteLine($"Name:{spell.Name} Source:{spell.Source} Page:{spell.Page} SRD:{spell.SRD} Time:{spell.Time}");
}
-david