I need some clarification on using Json.Utility.ToJson. In the documentation it says that plain classes must include the [Serializable] attribute. However take the following example:
using System;
using System.Collections.Generic;
using UnityEngine;
public class JsonTest : MonoBehaviour
{
void Start()
{
string json = SerializeToJson();
DeserializeFromJson(json);
}
string SerializeToJson()
{
NonSerializedClass instance = new NonSerializedClass();
string json = JsonUtility.ToJson(instance);
Debug.Log(json); // Result: {"valueOne":10,"valueTwo":20}
return json;
}
void DeserializeFromJson(string json)
{
NonSerializedClass instance = JsonUtility.FromJson<NonSerializedClass>(json);
Debug.Log(instance.valueOne); // Result: 10
}
}
public class NonSerializedClass
{
public int valueOne = 10;
public int valueTwo = 20;
}
In this example, the NonSerializedClass (as the name implies) does not use the [Serializable] attribute, yet it still gets serialized correctly, and deserialized correctly. I would expect this to return empty JSON as a result of not including the attribute.
However, if I try to place the class in a List<> then I get the results I expect, take the following example (NOTE: I still don’t include the attribute on the NonSerializedClass):
using System;
using System.Collections.Generic;
using UnityEngine;
public class JsonTest : MonoBehaviour
{
void Start()
{
string json = SerializeToJson();
DeserializeFromJson(json);
}
string SerializeToJson()
{
List<NonSerializedClass> dataList = new List<NonSerializedClass>();
dataList.Add(new NonSerializedClass();
dataList.Add(new NonSerializedClass();
dataList.Add(new NonSerializedClass();
NSList container = new NSList(dataList);
string json = JsonUtility.ToJson(container);
Debug.Log(json); // Result: {}
return json;
}
void DeserializeFromJson(string json)
{
NSList container = JsonUtility.FromJson<NSList>(json);
Debug.Log(container[0].valueOne); // Null reference
}
}
public class NonSerializedClass
{
public int valueOne = 10;
public int valueTwo = 20;
}
// Wrapper
public class NSList
{
public List<NonSerializedClass> dataList;
public NSList(List<NonSerializedClass> _dataList)
{
dataList = _dataList;
}
}
This behaves as expected, and returns an empty JSON and a Null Reference in the deserialization. This can be rectified by including the [Serializable] attribute. But this then begs the following question, how comes the Wrapper class does not need to include the Attribute in this circumstance?
I would like to know the following:
- Why does my NonSerialized class
correctly serialize to JSON without
the [Serializable] attribute? - When adding the class to a List<>
using a wrapper class to serialize
the List<>, how comes only the class
in the collection needs the
attribute, and not the wrapper class?