如何使用 Newtonsoft Json.Net 反序列化接口



我有这个类层次结构:

public class ProxyBotsSnapshotLogEntryDetails : IBotsSnapshotLogEntryDetails
{
public ICollection<IBotSnapshot> Snapshots { get; set; }
}
public class ProxyBotSnapshot : IBotSnapshot
{
public string Name { get; set; }
public ICollection<IBotSnapshotItem> States { get; set; }
}
public class ProxyBotSnapshotItem : IBotSnapshotItem
{
public int Count { get; set; }
public IrcBotChannelStateEnum State { get; set; }
}

及其相应的接口

public interface IBotsSnapshotLogEntryDetails
{
ICollection<IBotSnapshot> Snapshots { get; set; }
}
public interface IBotSnapshot
{
string Name { get; set; }
ICollection<IBotSnapshotItem> States { get; set; }
}
public interface IBotSnapshotItem
{
int Count { get; set; }
IrcBotChannelStateEnum State { get; set; }
}

我想从 JSON 反序列化:

var test = JsonConvert.DeserializeObject<ProxyBotsSnapshotLogEntryDetails>(entry.DetailsSerialized);

但是我收到一个错误,说牛顿软件无法转换接口。

我发现了这篇很有前途的文章:

https://www.c-sharpcorner.com/UploadFile/20c06b/deserializing-interface-properties-with-json-net/

但不确定如何使用该属性,因为在我的情况下,该属性是接口列表。

文章中提供的转换器工作得非常好,我只是缺少在集合属性上使用它的语法。以下是带有转换器和工作属性的代码:

// From the article
public class ConcreteConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<T>(reader);
}
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
public class ProxyBotsSnapshotLogEntryDetails : IBotsSnapshotLogEntryDetails
{
[JsonProperty(ItemConverterType = typeof(ConcreteConverter<ProxyBotSnapshot>))]
public ICollection<IBotSnapshot> Snapshots { get; set; }
}
public class ProxyBotSnapshot : IBotSnapshot
{
public string Name { get; set; }
[JsonProperty(ItemConverterType = typeof(ConcreteConverter<ProxyBotSnapshotItem>))]
public ICollection<IBotSnapshotItem> States { get; set; }
}
public class ProxyBotSnapshotItem : IBotSnapshotItem
{
public int Count { get; set; }
public IrcBotChannelStateEnum State { get; set; }
}

如果将以下设置添加到序列化程序和解序列化程序方法,则可能会起作用:

new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto}

例如:

var test = JsonConvert.DeserializeObject<ProxyBotsSnapshotLogEntryDetails>(entry.DetailsSerialized,
new JsonSerializerSettings 
{
TypeNameHandling = TypeNameHandling.Auto
});