JsonUtility.ToJson and [System.Serializable]

I have player’s profile which I need to send on server from time to time

[System.Serializable]
public class Profile
{
    public string email;
    public string name ;
    //***

    public List<CustomClass> problemList = new List<CustomClass>() { };
}

string jsonData = JsonUtility.ToJson(Profile))

The above code works, but this one doesn’t

string jsonData = JsonUtility.ToJson(Profile.problemList))

Why? JsonUtility can encode full profile, but when it comes to encode only one property from this profile it fails, it gives out “{}”, an empty strings.

As a solution I did following:

 [System.Serializable]
public class SubProblemList
{
    public List<CustomClass> list = new List<CustomClass>() { };
}
//*** copy property to temp class and json it.
string jsonData = JsonUtility.ToJson(new SubProblemList() { list = Profile.problemList })

The solution above works fine, but it’s too verbose. And in case I need to send some other profile’s properties independently, the code will become messy at the end.

How can I “json” only one property from “Serializable” object?

Unity’s JsonUtility has several limitations. First of all it has the same rules with a few extra limits as Unity’s normal serialization system. So only fields of supported types are serialized. In addition the json root object has to be an object. It can not be an array.

That’s why your second code snippet doesn’t work. If you want to assemble arbitrary json data you could use my SimpleJSON framework. This framework doesn’t use custom classes for every structure but simply uses classes to represent each json value. It’s designed to have a simple interface. However it doesn’t have an automatic custom class mapper. So you have to fill the data yourself.

JSONArray root = new JSONArray();

foreach(var problem in Profile.problemList)
{
    var obj = roof[-1].AsObject;
    obj["someFieldName"] = problem.someFieldName;
    obj["someOtherFieldName"] = problem.someOtherFieldName;
    // [ ... ]
}

Note that there is an extension file for some Unity engine types (Vector2/3/4, Matrix4x4, Quaternion, Rect, RectOffset) which can be stored either as object or array.

Though if your CustomClass is too complex you could use SimpleJSON just as “transcoder”. So you would still use Unity’s JsonUtility to convert your classes to json and parse that json with SimpleJSON. That way you can access any node you like and turn only that node back into json. Though I think that would be quite an overkill. When I use SimpleJSON I usually have my classes provide a Serialize and Deserialize method.

If this is also to verbose for you, you either have to use Unity’s JsonUtility and accept it’s limitations, or use a third party json mapper like Json.NET or some other alternatives.

1 Like

Json.NET exists also as Unity package (2020.1): https://docs.unity3d.com/2020.1/Documentation/Manual/com.unity.nuget.newtonsoft-json.html

2 Likes