0

I have a rest api app that is written in java (restlet, jackson). It's consumed using .net Newtonsoft.Json. The communication JSON contains polymorphic "@class" properties with "package.type" format. The JSON structure has arrays of different polymorphic derived class objects. The types are available in .net (not using converters for each type). So far what I am able to do in .net is set JsonSettings with TypeNameHandling with FormatterAssemblyStyle.Simple, create a custom SerializationBinder that handles the java package format to the .net FormatterAssemblyStyle.Simple format ("NamespaceExample.TypeName, AssemblyName"). So far so good, however I'd need to manually string replace "@class" with "$type" in the json before deserialization and vice versa after serialization for POST (update) operations. Do you know any better, more elegant way to do that replace automatically as part of the JsonSettings?

UPDATE: Example:

public class CustomSerializationBinder : DefaultSerializationBinder //cool magic
{
    private string _assemblyName = "Assembly.Name";

    public CustomSerializationBinder()
    {
    }

    public override void BindToName(
        Type serializedType, out string assemblyName, out string typeName)
    {
        assemblyName = null;
        typeName = serializedType.FullName;
    }

    public override Type BindToType(string assemblyName, string typeName)
    {
        var typeNameWithNamespace = $"{typeName}, {_assemblyName}";
        return Type.GetType(typeNameWithNamespace);
    }
}

public class Test
{
    private JsonSerializerSettings _settings = new JsonSerializerSettings()
    {
        //Doesn't work directly as it produces a $type property, not a @class as in java
        TypeNameHandling = TypeNameHandling.Auto,
        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple, //Exclude assembly version
        Binder = new CustomSerializationBinder()
    };

    [TestMethod]
    public void TypeNameHandlingTest()
    {
        var filePath = "resources\\json\\javaPolymorphicClassTyped.json";
        string json = "";
        using (StreamReader reader = new StreamReader(filePath))
        {
            json = reader.ReadToEnd();
        }

        // Magic that sucks when deserializing
        var jsonFixedType = json.Replace("\"@class\":", "\"$type\":");

        Assembly.Name.BaseType[] holderArr = JsonConvert.DeserializeObject<Assembly.Name.BaseType[]>(jsonFixedType, _settings);

        string jsonSerialized = JsonConvert.SerializeObject(holderArr, _settings);

        // Magic that sucks when serializing
        var jsonSerializedFixedType = jsonSerialized.Replace("\"$type\":", "\"@class\":");

        Assert.AreEqual(json, jsonSerializedFixedType);
    }
}

PS: I know the question is not perfect, but I am sure it's clear enough for the polymorphic serialization gurus that I expect to help + not much time to waste on it :)

Thank you!

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
vezenkov
  • 4,009
  • 1
  • 26
  • 27
  • 1
    Please give an example to demo what you want to achieve. – LHCHIN Nov 21 '19 at 02:21
  • 1
    Currently this is not implemented. See [JSON.Net - Change $type field to another name?](https://stackoverflow.com/q/9490345/3744182) whose answers have several workarounds. – dbc Nov 21 '19 at 19:09
  • yeah, ok, so I've got the workaround in my question already. Thanks – vezenkov Nov 22 '19 at 16:27

0 Answers0