我有一个我只想在反序列化时使用的转换器。所以我将 CanWrite 设置为 false,它工作正常并且一切都可以序列化。然后,Json 字符串包含一个对象图,其中有一个 SantaClauseCollection,其中包含一个 SantaClause 项目数组和一个 $type,表明它们是具体类型 SantaClause。
但是,当它在反序列化时遇到 SantaClaus 的集合时,它从不调用 CanConvert(我有一个断点并看到 SantaClausCollection,按 F5 继续,当遇到 SantaClaus 集合中的项目时,它应该再次点击断点,但它没有)。当它到达 SantaClaus 项目时,它不会尝试调用 CanConvert。甚至没有为该项目调用 CanConvert 来检查我的转换器是否会处理它,而是尝试自行反序列化它,这不起作用,因为该类没有默认构造函数,也没有具有属性名称匹配约定的构造函数:
找不到用于 SantaClaus 类型的构造函数。一个类应该有一个默认构造函数、一个带参数的构造函数或一个标有 JsonConstructor 属性的构造函数。
我理解为什么会出现这个错误,但问题是它表明 Json.net 试图反序列化对象,而不是调用 CanConvert 来检查我的转换器是否想要处理反序列化。
为什么没有为集合中的每个项目调用 CanConvert?
我的转换器:
class SantaClaus2JsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(SantaClaus);
}
/// <summary>
/// Deserializes a SantaClaus as a SantaClausEx which has a matching constructor that allows it to deserialize naturally.
/// </summary>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<SantaClausEx>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override bool CanRead
{
get
{
return true;
}
}
public override bool CanWrite
{
get
{
return false;//We only need this converter when reading.
}
}
}
SantaClausEx 只是继承自 SantaClaus 添加一个带有重命名参数的构造函数来匹配属性:
class SantaClaus //a third party class I can't modify
{
string Name {get;set;}
public SantaClaus(string santaClauseName) { this.Name = santaClauseName }
}
class SantaClausEx:SantaClaus
{
//provide a constructor with param names matching property names
public SantaClausEx(string name) : base(name)
}
Json.net 不能反序列化 SantaClaus,但它可以反序列化 SantaClauseEx。
我在任何地方都使用 SantaClauseEx 类,它工作得很好,但我想制作一个转换器来自动执行此操作。
这是集合中 Json 的样子:
SantaClausCollection: [
{
$type: "SantaClaus, XMasClasses.NET20"
Name: "St. Bob"
},
{
$type: "SantaClaus, XMasClasses.NET20"
Name: "St. Jim"
}
]