curiosity-ai / h5

🚀 The next generation C# to JavaScript compiler
https://github.com/curiosity-ai/h5
Apache License 2.0
210 stars 30 forks source link

Deserialize H5 Newtownsoft Json to deserialize a derived type class? #80

Open Riccsson opened 1 year ago

Riccsson commented 1 year ago

Is there any way to use H5 Newtownsoft Json to deserialize a derived type class?

Store the class type as a json-property and do a custom deserialize and check the property to create instance of correct type class? Any ideas?

ghost commented 1 year ago

I afraid no, H5 version is very limited.

The single option is to use implicit cast operator.

If it is OK for you to pass data as string and restore object from string using cast operator.
Then H5 JsonConvert will try to find cast operator and use it. So creation of object will be your responsibility and in your control.

theolivenbaum commented 1 year ago

You can store the type info in the json using a custom JsonSerializerSettings:

var jsonSettings = new JsonSerializerSettings 
                      {
                          TypeNameHandling = TypeNameHandling.Objects, 
                          SerializationBinder = AssemblyNameIgnoringSerializationBinder.Instance
                      };

var json = JsonConvert.SerializeObject(derivedObject, jsonSettings);
var deserialized = JsonConvert.DeserializeObject<BaseType>(json, jsonSettings);
ghost commented 1 year ago

You can store the type info in the json using a custom JsonSerializerSettings:

var jsonSettings = new JsonSerializerSettings 
                      {
                          TypeNameHandling = TypeNameHandling.Objects, 
                          SerializationBinder = AssemblyNameIgnoringSerializationBinder.Instance
                      };

var json = JsonConvert.SerializeObject(derivedObject, jsonSettings);
var deserialized = JsonConvert.DeserializeObject<BaseType>(json, jsonSettings);

Hmm, I never seen this option before. For example IContractResolver is empty, also we missing DataConverters.

Though as I see you cannot decide inside binder which Type to provide depending on data (only on type name):

public interface ISerializationBinder
  {
    Type BindToType(string assemblyName, string typeName);

    void BindToName(Type serializedType, out string assemblyName, out string typeName);
  }

Probably it is possible to provide different binders depending on manually extracted data. Is it the idea?