Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

[Solved] Creating a dynamic object to store complex Json data

Discussion in 'Scripting' started by ShermanZero, Oct 19, 2018.

  1. ShermanZero

    ShermanZero

    Joined:
    Dec 29, 2016
    Posts:
    11
    Hey all,

    I'm working on a project in which I want to be able to write simple key-value pairs into a JSON file using the JSON.net dependencies. Some of the values could also contain other key-value pairs, so there can be nested JSON data. For example:

    {
    "name":"foo",
    "id":0,
    "attributes":
    {
    "height":10,
    "slippery": true
    }
    }

    In working on writing the class that will contain all that, I ran into a Specified Cast is not Valid exception, and I suspect it's because of my limited knowledge of generic types. Here's the class:
    Code (CSharp):
    1. [System.Serializable]
    2. public class Data : JObject
    3. {
    4.     public void CreateChildUnderParent(string parent, string child)
    5.     {
    6.         Data obj = GetValueOfKey<Data>(parent);
    7.         obj.CreateChild(child);
    8.     }
    9.     public void CreateChild(string child)
    10.     {
    11.         AddKey(child, new Data());
    12.     }
    13.     public void AddKeyToParent(string parent, string key, JToken value)
    14.     {
    15.         Data parentObject = GetValueOfKey<Data>(key);
    16.         parentObject.AddKey(key, value);
    17.     }
    18.     public void AddKey(string key, JToken value)
    19.     {
    20.         Add(key, value);
    21.     }
    22.     public void RemoveKeyFromParent(string parent, string key)
    23.     {
    24.         Data parentObject = GetValueOfKey<Data>(key);
    25.         parentObject.RemoveKey(key);
    26.     }
    27.     public void RemoveKey(string key)
    28.     {
    29.         Remove(key);
    30.     }
    31.     public T GetValueFromParent<T>(string parent, string key)
    32.     {
    33.         Data parentObject = GetValue(key).ToObject<Data>();
    34.         return parentObject.GetValue(key).ToObject<T>();
    35.     }
    36.     public T GetValueOfKey<T>(string key)
    37.     {
    38.         foreach (var kvp in this)
    39.             if (kvp.Value is Data)
    40.             {
    41.                 T value = kvp.Value.ToObject<Data>().GetValueOfKey<T>(key);  //<-- error thrown here
    42.                 if (value != null)
    43.                     return value;
    44.             }
    45.         return GetValue(key).ToObject<T>();
    46.     }
    47. }
    The error is thrown within the public T GetValueOfKey<T>(string key) method. I'm not entirely sure why it's happening since I check the type of value before casting, so any help would be greatly appreciated! Thank you!
     
    Last edited: Oct 19, 2018
  2. ShermanZero

    ShermanZero

    Joined:
    Dec 29, 2016
    Posts:
    11
    Also I don't actually use "value" as my variable name within that function, that's just a placeholder to make it more obvious what the function returns, but the forum isn't letting me edit that out :(
     
  3. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,140
    If you are using json.net from the asset store, you can use this site

    http://json2csharp.com/

    and throw your json string in there to generate your class which you can deserialize your json into.
     
  4. ShermanZero

    ShermanZero

    Joined:
    Dec 29, 2016
    Posts:
    11
    Thanks for the reply! However, I don't want to create classes to represent my JSON data. I want it to be completely dynamic, so I don't have to write individual classes for every piece of data I want to store, because there's quite a bit. An ideal call to retrieve data would look like:

    dataObject.GetValueFromParent("attributes", "slippery"); //returns "true"
     
  5. ShermanZero

    ShermanZero

    Joined:
    Dec 29, 2016
    Posts:
    11
    Last edited: Oct 21, 2018