JSON.Net: deserializing polymorphic types without specifying the assembly

Posted by Frank Schwieterman on Stack Overflow See other posts from Stack Overflow or by Frank Schwieterman
Published on 2012-11-28T06:16:40Z Indexed on 2012/12/02 5:05 UTC
Read the original article Hit count: 275

Filed under:

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 typename without the assembly? I'd be happy to specify a default assembly to the JsonSerializer if thats possible

I am able to deserialize the JSON using:

public class SingleAssemblyJsonTypeBinder : SerializationBinder { private readonly Assembly _assembly; private Dictionary _typesBySimpleName = new Dictionary(StringComparer.OrdinalIgnoreCase); private Dictionary _simpleNameByType = new Dictionary();

    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;

© Stack Overflow or respective owner

Related posts about json.net