JSON.Net:在不指定程序集的情况下反序列化多态类型 [英] JSON.Net: deserializing polymorphic types without specifying the assembly

查看:115
本文介绍了JSON.Net:在不指定程序集的情况下反序列化多态类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到,如果$type属性指定了JSON对象的特定类型,则可以使用JSON.Net解码多态对象.在我看到的所有示例中,$type都包含名称空间.是否可以仅使用简单的类型名称而不使用程序集来完成这项工作?如果可能的话,我很乐意为JsonSerializer指定一个默认程序集.

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.

我可以使用以下方式反序列化JSON:

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);

尽管如此,我仍无法使用MVC进行这项工作.我正在按照Application_Start中的以下代码配置JSON反序列化,并且该对象已反序列化,但使用的是基本类型一.

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;

推荐答案

创建派生的SerializationBinder,其中覆盖BindToName并将out string assemblyName设置为null(编辑:或默认程序集)名称),然后将out string typeName更改为您的带区类型名称

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

在序列化之前将活页夹设置为JsonSerializerSettings.Binder.

Set the binder to the JsonSerializerSettings.Binder before serialisation.

让我知道这是否无效

这篇关于JSON.Net:在不指定程序集的情况下反序列化多态类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆