You shall not parse!

With a knowledge of the CREST API endpoints, requests can start being made for data - in Unity this is as simple as initialising a new WWW object with the specified endpoint URL. For example, a request for the history of an item on the market can be made with the following endpoint:

_www = new WWW("https://public-crest.eveonline.com/market/10000002/types/34/history/");

This will return a rather impressive JSON object containing nearly 400 entries for the price history of Tritanium in a market region known as The Forge. The problem here is that this string is pretty useless without being restructured in memory, the solution then is to parse or deserialise it into an object oriented .NET structure.

There are many ways to do this, SimpleJSON is a parser and builder written in C# but relies on knowing what index you are after. .NET's JSON Serialisation does a similar thing but converts directly to and from .NET Framework types. For the amount of data returned from the CREST API the latter solution would be preferred; being able to navigate a class structure representative of the JSON string.

And how about Unity?

Unity 5.3 comes to the rescue again, in this release the engine can now serialise and deserialise classes and structs marked with the System.Serialisable attribute. Unfortunately the class or struct type is needed before the deserialisation can be done with the Unity JsonUtility.

public static T FromJson<T>(string json); 

So how can the desired class structure be created when we do not know the structure of the source data? The Unity Manual suggests the following:

Deserialize the JSON into a class or struct that contains ‘common’ fields, and then use the values of those fields to work out what actual type you want. Then deserialize a second time into that type.

Not very helpful. Please welcome json2cshap.com. This tool will create the C# class structure from a JSON string - there's only a couple of things that need to be looked at.

By default the tool will create the members of any classes in the JSON string as properties, with getter and setter attributes. This appears to dissagree with Unity, so remove any getters/setters from the class and leave them as fields. The System.Serialisable attribute needs to be added to the classes too.

[System.Serialisable]
public class RootObject {
    public string totalCount_str;
    public List<Item> items;
    public int pageCount;
    public string pageCount_str;
    public int totalCount;
}

[System.Serialisable]
public class Item {
    public string volume_str;
    public int orderCount;
    public double lowPrice;
    public double highPrice;
    public double avgPrice;
    public double volume;
    public string orderCount_str;
    public string date;
}

This makes it possible to deserialise the item history into the above class structure using the code below.

RootObject _history = new RootObject();
_history = JsonUtility.FromJson<RootObject>(_www.text);

By default the json2csharp.com tool will use generic class names such as RootObject and Item, all that needs doing is changing these to something more semantic such as ItemHistory and HistoryEntry for example.

Links in this post