0

I am trying to read a json file into my C# code. The json file contains the following string:

{
    "allLevels": [{
        "level": 1,
        "name": "XXX",
        "type": "XXX",
        "description": "XXX",
        "input": "XXX",
        "key": "XXX",
        "keyType": "XXX",
        "output": "XXX"
    },
    {
        "level": 2,
        "name": "XXX",
        "type": "XXX",
        "description": "XXX",
        "input": "XXX",
        "key": "XXX",
        "keyType": "XXX",
        "output": "XXX"
    }],
    "funFacts": [
        "XXX",
        "XXXXX"     
        ]
}

I have two classes, namely AllLevel.cs and ContentJson.cs which are shown as follows:

[System.Serializable]
public class AllLevel
{
    public int level { get; set; }
    public string name { get; set; }
    public string type { get; set; }
    public string description { get; set; }
    public string input { get; set; }
    public object key { get; set; }
    public string keyType { get; set; }
    public string output { get; set; }
}

using System.Collections.Generic;
[System.Serializable]
public class ContentJson
{
    public IList<AllLevel> allLevels { get; set; }
    public IList<string> funFacts { get; set; }
}

I am able to read the .json file, but not able to assign it to the ContentJson object. The debug log in the code snippet below prints nothing but the string "ContentJson", and any attempt to access stuff inside the object gives NullReferenceException. Why is the FromJson not able to deserialize the object.

public static void populateGamedata(string gameDataFileName)
{
    if (gameDataFileName == null)
        return;
    // Path.Combine combines strings into a file path
    // Application.StreamingAssets points to Assets/StreamingAssets in the Editor, and the StreamingAssets folder in a build        
    string filePath = Path.Combine(Application.streamingAssetsPath, gameDataFileName);
    if (File.Exists(filePath))
    {
        // Read the json from the file into a string
        string dataAsJson = File.ReadAllText(filePath);
        // Pass the json to JsonUtility, and tell it to create a ContentJson object from it
        ContentJson gameData = JsonUtility.FromJson<ContentJson>(dataAsJson);

        // Retrieve the levels and funfacts property of gameData
        levels = gameData.allLevels;
        funFacts = gameData.funFacts;
        Debug.Log("dataAsJson === " + dataAsJson);
        Debug.Log("gameData == " + gameData.ToString());
        Debug.Log("levels == " + levels[0].name);            
    }
    else
    {
        Debug.LogError("Cannot load game data!");
    }
}

enter image description here PS: I created the json file manually.

Vipin Verma
  • 5,330
  • 11
  • 50
  • 92
  • 2
    Using JSON.NET, your JSON/C# classes [match up fine](http://rextester.com/NBC99701). I'm assuming it's something specific to Unity's JsonUtility. – ProgrammingLlama Jul 11 '18 at 01:32
  • I've tried using Newtonsoft.json and everything seems fine. Are you sure that the data is being loaded correctly? Take a look to dataAsJson to see if the json string is ok – Andre.Santarosa Jul 11 '18 at 01:35
  • Yes, `dataAsJson ` is being populated correctly, updated the screenshot in question for this. – Vipin Verma Jul 11 '18 at 01:36
  • I think it could be your get/set properties. https://stackoverflow.com/a/41787127/2322474 – KennyC Jul 11 '18 at 01:36
  • @KennyC should I remove get/set. let me try.. – Vipin Verma Jul 11 '18 at 01:38
  • @KennyC getting the same error after removing get/set – Vipin Verma Jul 11 '18 at 01:40
  • Just a quick one, why is your key property set to Type object if you pass a string like with all the other properties in the AllLevel class? – Andre Lombaard Jul 11 '18 at 01:42
  • yes it should be string, sorry my bad. but even after updating it, it doesn't work @user65439 – Vipin Verma Jul 11 '18 at 01:45
  • Have a look at this thread https://stackoverflow.com/questions/36239705/serialize-and-deserialize-json-and-json-array-in-unity, they mention that you should use JsonHelper instead of JsonUtility when working with arrays. Look at the Troubleshooting JsonUtility section of the answer – Andre Lombaard Jul 11 '18 at 02:00
  • yes, I was reading through that one. Thanks! – Vipin Verma Jul 11 '18 at 02:02
  • from my understanding of that post above, i'd have to split my json file into two separate files, each containing arrays. is it? i.e. go from {key1:jsonarray[json1, json2],key2:stringarray} to two files first corresponding to key1, and second for key2 – Vipin Verma Jul 11 '18 at 02:12
  • 1.Remove the `{ get; set; }` from the variable names. 2. `allLevels` and `funFacts` should both be type of `List` not `IList` because Unity only supports basic contains(No ILIst, Dictionary or similar stuff). Also, your key should be type of `string` not `object`. Please use [this](http://json2csharp.com/) to generate your json. Don't forget to remove `{ get; set; }` from the new json and don't forget to place `[System.Serializable]` on top of the classes. Finally, you do not need `JsonHelper` in this because it's **not** json array. `JsonUtility` alone should be fine – Programmer Jul 11 '18 at 02:14
  • i used the jsonTocsharp utility to generate the classes, and it gave me the AllLevel and ContentJson classes which I posted above. Thank you for your suggestions, I will try this – Vipin Verma Jul 11 '18 at 02:18
  • Thanks @Programmer, it worked. I just needed to use List instead of IList, as suggested by jsonToCsharp utility – Vipin Verma Jul 11 '18 at 02:20
  • Can you post this as an answer. I will accept it :) – Vipin Verma Jul 11 '18 at 02:21
  • It's a duplicate and can't copy the-same thing over again. Although, an upvote to my other answer fine to show that it was helpful to you. It looks like you have already upvoted it so you should be fine. – Programmer Jul 11 '18 at 02:27

0 Answers0