Hey,
This is probably quite simple for some but I have spent many hours on this now and really hope someone can help out.
I’m trying to use this JSON file I get from an API. I am even unsure IF the Unity JSONUtility is capable of parsing this JSON at all?
Anything inside braces - { and } - is an object. So the entire file is an object with a single property “products” which is an array. The array is a list of objects. Each of those objects has some individual fields (id, name, description), and also several fields which are themselves objects (productNumber, price, sellingPrice, links).
Your C# class will need to replicate the same structure, so for example you’ll need a ProductNumber class which has Value and Formatted fields, and your Product class would have a productNumber property of type ProductNumber.
There’s a bit of ambiguity on some of the fields - whether they should be considered classes or Dictionaries, which have the same representation in JSON. For instance, the _links field:
class Link {
public string href;
public string method;
}
// Method A:
public Links _links;
public class Links {
Link website;
}
// Method B:
public Dictionary<string,Link> _links;
// Method C:
public Dictionary<string,Dictionary<string,string>> _links;
So if you have any documentation for what this JSON is supposed to contain, that would be a good place to start.
JsonUtility can’t handle a Dictionary so you’ll have to use strong named classes:
public class ProductCollection
{
public List<Product> products {get; set;}
}
public class Product
{
public int id {get; set;}
public string name {get; set;}
public string description {get; set;}
public ProductNumber productNumber {get; set;}
public PriceDefinition price {get; set;}
public PriceDefinition sellingPrice {get; set;}
public Manufacturer manufacturer {get; set;}
public Links _links {get; set;}
}
public struct ProductNumber
{
public string value {get; set;}
public string formatted {get; set;}
}
public struct PriceDefinition
{
public decimal amount {get; set;}
public string currencyCode {get; set;}
}
public struct Manufacturer
{
public string name {get; set;}
public string location {get; set;}
}
public struct Links
{
public Website website {get; set;}
}
public struct Website
{
public string href {get; set;}
public string method {get; set;}
}
Of course those structs could be classes. Using structs results in less GC allocation but makes them default to byval instead of byref and more expensive when passing them to methods.
These structure should be simple enough with JsonUtility. With JSON .NET it would be simply:
var prodCollection = JsonConvert.DeserializeObject<ProductCollection>(jsonString);
I really like the json.net asset, but you should be able to use unitys json also if you just need a free version. Also note a good link is http://json2csharp.com/
If you toss your json file into it, it will then spit out the classes and properties you need for you so you know how to structure your class to deserialize into.
There is also
Which will help you track down an error in your json structure if it fails.
Thanks a lot everyone, I think I have gotten further. I went for Dustin’s class setup.
So now I am trying to access the data, but am failing so far:
void Start(){
//get local JSON file from Resources folder
string json = getJsonData ();
ProductCollection data = JsonUtility.FromJson<ProductCollection>(json);
//Test the ID
Debug.Log (data.products[1].id);
}
I suppose this is wrong?
data.products.Count; gives a NullReferenceException…
That “Account” was a poor copy from another test (I was trying with another more simple setup).
So the structure is:
[Serializable]
public class ProductCollection
{
public List<Product> products {get; set;}
}
[Serializable]
public class Product
{
public int id {get; set;}
public string name {get; set;}
public string description {get; set;}
public ProductNumber productNumber {get; set;}
public PriceDefinition price {get; set;}
public PriceDefinition sellingPrice {get; set;}
public Manufacturer manufacturer {get; set;}
public Links _links {get; set;}
}
[Serializable]
public struct ProductNumber
{
public string value {get; set;}
public string formatted {get; set;}
}
[Serializable]
public struct PriceDefinition
{
public decimal amount {get; set;}
public string currencyCode {get; set;}
}
[Serializable]
public struct Manufacturer
{
public string name {get; set;}
public string location {get; set;}
}
[Serializable]
public struct Links
{
public Website website {get; set;}
}
[Serializable]
public struct Website
{
public string href {get; set;}
public string method {get; set;}
}
And then I try to get any variable displayed in the Debug, but I fail…
void Start(){
//get local JSON file from Resources folder
string json = getJsonData ();
ProductCollection data = JsonUtility.FromJson<ProductCollection>(json);
//Test if JsonUtility has worked??
Debug.Log (data.products[1].id);
}
I can’t seem to access the variables in any way. I suspect it’s not working.
tried:
Debug.Log (data.products[1].id) → console says: NullReferenceException
Debug.Log (data.products.Count) → console says: NullReferenceException
Debug.Log (data) → console says: AccountCollection
I believe you have to use the SerializableField attribute on properties for them to be properly serializable in Unity.
Try this instead:
[Serializable]
public class ProductCollection
{
public List<Product> products;
}
[Serializable]
public class Product
{
public int id;
public string name;
public string description;
public ProductNumber productNumber;
public PriceDefinition price;
public PriceDefinition sellingPrice;
public Manufacturer manufacturer;
public Links _links;
}
[Serializable]
public struct ProductNumber
{
public string value;
public string formatted;
}
[Serializable]
public struct PriceDefinition
{
public decimal amount;
public string currencyCode;
}
[Serializable]
public struct Manufacturer
{
public string name;
public string location;
}
[Serializable]
public struct Links
{
public Website website;
}
[Serializable]
public struct Website
{
public string href;
public string method;
}