I see that using JSON.Net, I can decode polymorphic objects if a $type
attribute specifies the specific type of the JSON object. In all the examples I've seen, $type
includes the namespace. Is it possible to make this work including just a simple type name without the assembly? I'd be happy to specify a default assembly to the JsonSerializer if that's possible.
I am able to deserialize the JSON using:
public class SingleAssemblyJsonTypeBinder : SerializationBinder
{
private readonly Assembly _assembly;
private Dictionary<string, Type> _typesBySimpleName = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
private Dictionary<Type,string> _simpleNameByType = new Dictionary<Type, string>();
public SingleAssemblyJsonTypeBinder(Assembly assembly)
{
_assembly = assembly;
_typesBySimpleName = new Dictionary<string, Type>();
foreach (var type in _assembly.GetTypes().Where(t => t.IsPublic))
{
if (_typesBySimpleName.ContainsKey(type.Name))
throw new InvalidOperationException("Cannot user PolymorphicBinder on a namespace where multiple public types have same name.");
_typesBySimpleName[type.Name] = type;
_simpleNameByType[type] = type.Name;
}
}
public override Type BindToType(string assemblyName, string typeName)
{
Type result;
if (_typesBySimpleName.TryGetValue(typeName.Trim(), out result))
return result;
return null;
}
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
string name;
if (_simpleNameByType.TryGetValue(serializedType, out name))
{
typeName = name;
assemblyName = null;// _assembly.FullName;
}
else
{
typeName = null;
assemblyName = null;
}
}
}
...
public static JsonSerializerSettings GetJsonSerializationSettings()
{
var settings = new JsonSerializerSettings();
settings.Binder = new SingleAssemblyJsonTypeBinder(typeof(MvcApplication).Assembly);
settings.TypeNameHandling = TypeNameHandling.Objects;
return settings;
}
...
var serializer = JsonSerializer.Create(settings);
I haven't been able to make this work with MVC though. I'm configuring JSON deserialization per the code below in Application_Start
, and the object is deserialized, but using the base type one.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Binder = new SingleAssemblyJsonTypeBinder(this.GetType().Assembly);
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.All;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple;
Create a derived SerializationBinder
in which override BindToName
and Set out string assemblyName
to null (Edit: or your default assembly name) and out string typeName
to your striped type name
Set the binder to the JsonSerializerSettings.Binder
before serialisation.
Let me know if this is not working
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With