2

Here is my JSON file for testing purposes :

{"timestamp":4455518515,"profileId":"5asd15qwe11as2d12q1sd","profileName":"player01",
"textures":{"material":{"url":"http://materialurl.com/aksjd54854we5a4sd.png"}}}

I want to reach textures -> material -> url but i can't. Here is my code :

public class JsonTest : MonoBehaviour {

string json;
string path;

// Use this for initialization
void Start () {
    path = Application.streamingAssetsPath + "/json.txt";
    json = File.ReadAllText(path);

    MaterialJson test = JsonUtility.FromJson<MaterialJson>(json);

    Debug.Log(test.timestamp);
    Debug.Log(test.profileId);
    Debug.Log(test.profileName);
    Debug.Log(test.textures);
    }
}

[Serializable]
public class MaterialJson
{
    public double timestamp;
    public string profileId;
    public string profileName;
    public string textures;
}

There is no problem for first three variables. But textures returns null in debug log. I have no idea how can I take nested variables in textures. Is unity's JsonUtility capable of that ? I couldn't find any info on unity's documentation.

It's worked perfectly with the code below : (Thanks to @mrfreester)

[Serializable]
public class MaterialJson
{
    public double timestamp;
    public string profileId;
    public string profileName;
    public Textures textures;
}
[Serializable]
public class Textures
{
    public Material material;
}

[Serializable]
public class Material
{
    public string url;
}

Debug.Log(test.textures.material.url);
sword1st
  • 525
  • 3
  • 7
  • 21
  • textures is not a string but a JSON object – Quintium Jan 26 '18 at 21:02
  • What does `Debug.Log(test.textures.material);`? – Liora Haydont Jan 26 '18 at 21:02
  • 1
    This isn't an area I have a ton of experience in... but it looks like you're expecting `textures` to be a `string` here... `public string textures`... However it's an object in your json. You probably would need to create a Serializable class `textures`, which contains a `material` class, which contains a `public string url` if you want it to work with your json. – mrfreester Jan 26 '18 at 21:02
  • @Quintium Yep but i have no idea how can i parse that object too. – sword1st Jan 26 '18 at 22:05
  • @mrfreester Thanks for the tip. I tried something like that with following your comment : [Serializable] public class MaterialJson { public double timestamp; public string profileId; public string profileName; Textures texture; } [Serializable] public class Textures { Material material; } [Serializable] public class Material { public string url; } But i have no idea how can access that url through this pattern ? Can you give me an example please ? (It's looks bad i will edit my question with this code) – sword1st Jan 26 '18 at 22:05
  • 1
    @mrfreester Ohh it's worked with this code Debug.Log(test.texture.material.url); Thank you so much for the help. You can write it as a solution – sword1st Jan 26 '18 at 22:16
  • @sword1st great thank you! There might be some other approaches to simplify the object structure that would work better for you, but if you plan on textures and materials to potentially have more properties, it probably makes the most sense to leave the structure this way. Good luck with your game/app :) – mrfreester Jan 26 '18 at 22:52
  • Your json and the structure you created don't match, Always use external websites to create the structures if you are confused. Paste the json [here](http://json2csharp.com/) and it will give you the correct value. The duplicate mentions this and other reasons you may get null. – Programmer Jan 26 '18 at 23:00

2 Answers2

1

Method 1:

You can use this:

using (var ms = new System.IO.MemoryStream(Encoding.Unicode.GetBytes(json)))
{
   System.Runtime.Serialization.Json.DataContractJsonSerializer deserializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(MaterialJson));
   MaterialJson test = (MaterialJson)deserializer.ReadObject(ms);
}

Method 2:

Thanks to Newtonsoft and JSON.Net, you can try this:

var test =  JsonConvert.DeserializeObject<MaterialJson>(json);

and the MaterialJson class as below:

[Serializable]
public class MaterialJson
{
    public double timestamp;
    public string profileId;
    public string profileName;
    public texturesType textures;
    public class texturesType
    {
        public materialType material;
        public class materialType
        {
            public string url;
        }
    }
}

Now you can access the url property using: test.textures.material.url

Vahid Farahmandian
  • 6,081
  • 7
  • 42
  • 62
  • Thank you for your comment but actually i don't wanna use any other library cuz i will publish it on mobile platform and i have no idea if it's work or not – sword1st Jan 26 '18 at 22:08
  • @sword1st I have updated the answer. please check again – Vahid Farahmandian Jan 26 '18 at 22:23
  • +1 for the nested classes if those wouldn't be used in other places. For unity's built in JasonUtility they would probably also have to be marked with `[Serializable]` – mrfreester Jan 27 '18 at 03:13
1

It looks like you're expecting textures to be a string here

public string textures;

However it's an object in your json.

You could create a Serializable class for each associated json object if you want it to work with your json in its current format. As stated in your comment:

[Serializable] 
public class MaterialJson 
{ 
    public double timestamp; 
    public string profileId; 
    public string profileName; 
    Textures texture; 
} 

[Serializable] 
public class Textures 
{ 
    Material material; 
} 

[Serializable] 
public class Material 
{ 
    public string url; 
}

Which would then be accessed like this:

Debug.Log(test.texture.material.url);
mrfreester
  • 1,981
  • 2
  • 17
  • 36