对嵌套类型使用JSON.net Binder/TypeNameHandling

本文关键字:Binder TypeNameHandling net JSON 嵌套类型 | 更新日期: 2023-09-27 18:30:13

使用JSON.net,我想反序列化从抽象类继承的类型列表。我使用过类似的KnownTypesBinder(来源)

var jsonSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.TypeNameHandling = TypeNameHandling.Auto;
jsonSettings.Binder = new KnownTypesBinder { KnownTypes = new List<Type> { ... } };

现在这在WEB API模型绑定器中工作得非常好KnownTypesBinder.BindToType正在被调用,对象可以被反序列化。在web应用程序的另一部分,我必须反序列化JSON字符串,因此我希望重用相同的JsonFormatter。根据文件,以下内容应该有效;

JsonConvert.DeserializeObject<T>(String, JsonSerializerSettings);

然而,当我这样做的时候:

JsonConvert.DeserializeObject<A>(jsonString, GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings);

引发以下错误:

JsonSerializationException。无法创建类型C的实例。类型是接口或抽象类,无法实例化。

我的类型看起来像这样;

class A {
    public B B { get; set; }
}
class B {
    public List<C> C { get; set; }
}
abstract class C { }
class C1: C { }
class C2: C { }

另外,创建一个新的JsonSerializerSettings并设置BinderTypeNameHandling也没有什么区别。我发现KnownTypesBinder.BindToType根本没有被调用。JSON.net中有我遗漏的东西吗?

对嵌套类型使用JSON.net Binder/TypeNameHandling

在这里感觉很愚蠢。JSON.net使用的鉴别器称为"$type"。当我使用curl发送POST负载时,bash尝试将$type解析为环境变量。由于没有这样的变量,最终的JSON只是{"": "C"}而不是{"$type": "C"}