Unity Serializing Nested Dictionary to JSON
JsonUtility is the fastest way to use jsons as it doesn't generate almost any GC. The problem is that it isn't very flexible because you need to know in advance the data structure and it cannot be mutated as it needs a class.
If you need to use Jsons as dictionaries you can use either MiniJSON (just right clic and Save As...) or JSONObject, both are free and work in every platform altough they are a lot slower than JsonUtilty, so if you are parsing big jsons or need to do it a lot of times while the performance matters then it isn't going to be fluid.
I personally have used both and they are great, MiniJSON is a bit easier to use while JSONObject is a little bit more potent but also a little bit more difficult to start with.
EDIT:
As mentioned in one of the comments you can also use Newtonsoft, I think it is faster than minijson and jsonobject but might be overkill if you aren't doing a lot of stuff with jsons.
hotshotiguana
Updated on June 19, 2022Comments
-
hotshotiguana almost 2 years
The REST service I am using, RSA Archer, is expecting an integer key which means I simply can't nest
[Serializable]
objects and thenJsonUtility.ToJson()
to create the serialized JSON string. I thought I found a solution to create aDictionary
object and then useISerializationCallbackReceiver
to handle just the dictionary piece of the nested structure, but the code below simply ignores that part of the nested object and doesn't serialize theDictionary
. Does anyone have any thoughts on the best approach to this?Expected Output:
{"Content": {"LevelId": 10,"FieldContents": {"47": {"Type": 1, "Value": "me", "FieldId": 47}}}}
Object Structure:
[Serializable] public class Record { public Content Content; } [Serializable] public class Content { public int LevelId; public FieldContents FieldContents; } public class FieldContents : ISerializationCallbackReceiver { public Dictionary<string, FieldValue> FieldValues; public List<string> dicKeys; public List<FieldValue> dicVals; public void OnBeforeSerialize () { dicKeys.Clear (); dicVals.Clear (); foreach (var kvp in FieldValues) { dicKeys.Add (kvp.Key); dicVals.Add (kvp.Value); } } public void OnAfterDeserialize () { FieldValues = new Dictionary<string, FieldValue> (); for (int i = 0; i < Math.Min (dicKeys.Count, dicVals.Count); i++) { FieldValues.Add (dicKeys [i], dicVals [i]); } } } [Serializable] public class FieldValue { public int Type; public string Value; public int FieldId; }
JSONUtility and Instantiation:
Record newRecord = new Record () { Content = new Content () { LevelId = 10, FieldContents = new FieldContents () { FieldValues = new Dictionary<string, FieldValue> () { { "47", new FieldValue () { Type = 1, Value = "me", FieldId = 47 } } } } } }; Debug.Log (JsonUtility.ToJson (newRecord));
-
hotshotiguana about 7 yearsThanks @Juan. I am certainly not opposed to 3rd party libraries, but when I used LitJSON to do this I ran into many issues getting it to work with the Hololens, hence the fallback to JsonUtility. I will test out those other libraries and see how they do.
-
Juan Bayona Beriso about 7 yearsI recommend you minijson if you don't need to parse big jsons, it's only a script and it is super easy to use. Google and Facebook are using it in their sdks for unity