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

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

问题描述

我看到使用 JSON.Net,如果 $type 属性指定 JSON 对象的特定类型,我可以解码多态对象.在我见过的所有示例中,$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(Edit: 或您的默认程序集名称)和 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

在序列化之前将 binder 设置为 JsonSerializerSettings.Binder.

Set the binder to the JsonSerializerSettings.Binder before serialisation.

如果这不起作用,请告诉我

Let me know if this is not working

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

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