-
Notifications
You must be signed in to change notification settings - Fork 266
Deserializing type object with generated serializer #52
Comments
You can't add StandardResolver for IL2CPP. Utf8Json.Resolvers.CompositeResolver.RegisterAndSetAsDefault(
new[] { PrimitiveObjectFormatter.Default },
new[] { Utf8Json.Resolvers.GeneratedResolver.Instance, Utf8Json.Resolvers.BuiltinResolver.Instance }); for the performance, you can write custom formatter? public class CustomObjectResolver : IJsonFormatter<object>
{
static readonly IJsonFormatter<DisplayAction> displayActionFormatter = new DisplayActionFormatter();
// or other formatters...
public void Serialize(ref JsonWriter writer, object value, IJsonFormatterResolver formatterResolver)
{
throw new NotImplementedException(); // if serialize support, hmn....
}
public object Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
{
// throw new NotImplementedException();
if (reader.GetCurrentJsonToken() == JsonToken.BeginObject)
{
var savedReader = reader; // copy struct(save offset index)
// if always first property is ___TYPE, can read immediately
if (reader.ReadPropertyName() == "___TYPE")
{
var typeName = reader.ReadString();
switch (typeName)
{
case "DisplayAction":
// pass savedReader.
return displayActionFormatter.Deserialize(ref savedReader, formatterResolver);
// case "": ....
default:
break;
}
}
}
// fallback, use primitiveobjectformatter.
return PrimitiveObjectFormatter.Default.Deserialize(ref reader, formatterResolver);
}
} |
Thank you very much for your response. I have a question about number 2. When I implement this code to create a custom formatter for object, I get the following error:
This occurs on the the line:
Any ideas what could be causing this? |
sorry, I've forget public class CustomObjectFormatter : IJsonFormatter<object>
{
static readonly IJsonFormatter<DisplayAction> displayActionFormatter = new DisplayActionFormatter();
// or other formatters...
public void Serialize(ref JsonWriter writer, object value, IJsonFormatterResolver formatterResolver)
{
throw new NotImplementedException(); // if serialize support, hmn....
}
public object Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
{
if (reader.GetCurrentJsonToken() == JsonToken.BeginObject)
{
var count = 0;
while (reader.ReadIsInObject(ref count))
{
var savedReader = reader; // copy struct(save offset index)
// if always first property is ___TYPE, can read immediately
if (reader.ReadPropertyName() == "___TYPE")
{
var typeName = reader.ReadString();
switch (typeName)
{
case "DisplayAction":
// pass savedReader.
return displayActionFormatter.Deserialize(ref savedReader, formatterResolver);
// case "": ....
default:
break;
}
}
}
}
// fallback, use primitiveobjectformatter.
return Utf8Json.Formatters.PrimitiveObjectFormatter.Default.Deserialize(ref reader, formatterResolver);
}
} |
Thank you again, you have been a great help and I have made a lot of progress. I do have a follow-up question about the custom deserializer. If I deserialize to an object, and it comes out as an object with a specific type of Dictionary<string, object>, is there a way to then convert selected objects within that to a specific type? I have some instances where objects are deeply nested in and I don't necessarily want them to be deserialized all up front. I want to be able to take some objects out of the dictionary and, through a second pass, convert them from Dictionary<string, object> to the actual specific type, such as DisplayAction (from the example above). With the current library that is in use in my project, which is LitJson, there is an option to deserialize to its internal format, JsonData, and then further deserialize subsections of that again to more specific types. Is that possible with Utf8Json? In other words, once I deserialize to can I then re-deserialize the resulting objecting to a specific class? |
First of all, thank you for this fantastic library. It has shown huge improvements for me over other libraries I've tried.
I am in the process of converting a Unity project that currently uses LitJson to use Utf8Json, due to big garbage creation and memory savings my testing has shown Utf8Json provides. One of the requirements of my project is that it must be compatible with existing JSON files as input, which means I can't use a solution that requires I re-serialize or modify the input data structure in any way. Because my Unity build uses IL2CPP, I am using the Universal Code Generator utility, but I have a couple of questions.
Utf8Json.Resolvers.CompositeResolver.RegisterAndSetAsDefault (Utf8Json.Resolvers.GeneratedResolver.Instance, Utf8Json.Resolvers.BuiltinResolver.Instance);
The second parameter is what I found I needed to add to deserialize primitive objects. However, if I add the Standard Resolver as a parameter, as is shown in the example usage of the Universal Code Generator utility, I receive the same error at runtime on an iOS device as if I don't pre generate code, which is the NotSupportedException regarding System.Reflection.Emit.
Is there a different parameter I have to add in order to support the object type, or do I have to modify my generated resolver class to accommodate it? If so, how so?
The custom deserializer deserializes each of these objects into their respective types; in this case, it would be a DisplayAction object and a PlaySoundAction object. Is there a way to deserialize something like this?
Within the Unity Editor (I can't deserialize to Object yet on iOS because of my previous question), if I simply deserialize this into a List of type Object, the result that I have seen is of type Dictionary<string, object>. Is there a way, after deserialization, to then convert this to the final object type, such as (from the example above) DisplayAction or SoundAction?
Thank you for your help.
The text was updated successfully, but these errors were encountered: