Hello!
I solving a problem with deserialize json to complex dynamic type using Unity JsonUtility. And have some issue with which I need help.
First, I create a simple dynamic type with C# TypeBuilder. This type contains one string field. This type deserialised fine.
using System;
using System.Reflection;
using System.Reflection.Emit;
using UnityEngine;
public static class JsonDynamicTypeDeserializer
{
private static TypeBuilder GenerateDynamicTypeBuilder(string name, ModuleBuilder mb, AssemblyName an)
{
var typeBuilder = mb.DefineType($"{name}",
TypeAttributes.Public
| TypeAttributes.Class
| TypeAttributes.Serializable,
parent: null);
return typeBuilder;
}
public static void SimpleDynamicTypeDeserialize()
{
var an = new AssemblyName("DynamicAssembly");
var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
var mb = ab.DefineDynamicModule(an.Name);
var simpleTb = GenerateDynamicTypeBuilder("Simple", mb, an);
simpleTb.DefineField("string_data", typeof(string), FieldAttributes.Public);
var simpleT = simpleTb.CreateType();
dynamic data = JsonUtility.FromJson("{\"string_data\":\"Hello World!\"}", simpleT);
Debug.Log($"string_data='{data.string_data}'");
}
}
Output: string_data='Hello World!'
Then I create a complex dynamic type with C# TypeBuilder. This type contains that simple dynamic typed field. This type not deserialized.
using System;
using System.Reflection;
using System.Reflection.Emit;
using UnityEngine;
public static class JsonDynamicTypeDeserializer
{
private static TypeBuilder GenerateDynamicTypeBuilder(string name, ModuleBuilder mb, AssemblyName an)
{
var typeBuilder = mb.DefineType($"{name}",
TypeAttributes.Public
| TypeAttributes.Class
| TypeAttributes.Serializable,
parent: null);
return typeBuilder;
}
public static void ComplexDynamicTypeDeserialize()
{
var an = new AssemblyName("DynamicAssembly");
var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
var mb = ab.DefineDynamicModule(an.Name);
var simpleTb = GenerateDynamicTypeBuilder("Simple", mb, an);
simpleTb.DefineField("string_data", typeof(string), FieldAttributes.Public);
var simpleT = simpleTb.CreateType();
var complexTb = GenerateDynamicTypeBuilder("Complex", mb, an);
complexTb.DefineField("complex_data", simpleT, FieldAttributes.Public);
var complexT = complexTb.CreateType();
dynamic data = JsonUtility.FromJson("{\"complex_data\":{\"string_data\":\"Hello World!\"}}", complexT);
Debug.Log($"complex_string_data='{data.complex_data?.string_data}'");
}
}
Output: complex_string_data=''
Then for test I create another complex dynamic type with C# TypeBuilder. This type contains non dynamic simple typed field. This type deserialized fine.
using System;
using System.Reflection;
using System.Reflection.Emit;
using UnityEngine;
public static class JsonDynamicTypeDeserializer
{
private static TypeBuilder GenerateDynamicTypeBuilder(string name, ModuleBuilder mb, AssemblyName an)
{
var typeBuilder = mb.DefineType($"{name}",
TypeAttributes.Public
| TypeAttributes.Class
| TypeAttributes.Serializable,
parent: null);
return typeBuilder;
}
[Serializable]
public class SimpleData
{
public string string_data;
}
public static void ComplexDynamicTypeWithNonDynamicFieldDeserialize()
{
var an = new AssemblyName("DynamicAssembly");
var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
var mb = ab.DefineDynamicModule(an.Name);
var complexTb = GenerateDynamicTypeBuilder("Complex", mb, an);
complexTb.DefineField("complex_data", typeof(SimpleData), FieldAttributes.Public);
var complexT = complexTb.CreateType();
dynamic data = JsonUtility.FromJson("{\"complex_data\":{\"string_data\":\"Hello World!\"}}", complexT);
Debug.Log($"complex_string_data='{data.complex_data?.string_data}'");
}
}
Output: complex_string_data='Hello World!'
Is this a limitation of JsonUtility? Or I miss something?
P.S.
I found source code of JsonUtility.bindings.cs
But this source code no help.
Is there any way to look at source code of JsonUtility deeper (FromJsonInternal method)?