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!