JSON.NET,如果期望的对象未能反序列化,则实例化回退对象
本文关键字:对象 反序列化 实例化 回退 如果 期望 JSON NET | 更新日期: 2023-09-27 18:30:10
我有一个项目树,我正试图使用JSON.NET对其进行反序列化。在某些情况下,例如重命名节点类型,树上的节点可能无法反序列化。
在这些情况下,我想插入一个节点的默认实例(可能是其他类型)来代替未反序列化的对象。
这样,我的用户仍然可以加载他们的保存文件,得到一个他们必须修复的"空"节点。。。但是,至少他们仍然可以加载他们的文件!
我一直在做一些研究,并尝试使用SerializationBinder和/或在序列化程序的回调中破解一些错误处理,但我倾向于问,以防我缺少一些明显的解决方案,或对这些方法的输入。
如果重要的话,这是一个正在快速发展的内部工具,我们预计时不时会有一些破碎的树,我们真的只希望它们能加载,不管怎样:)
谢谢!
我发现了一些东西,非常感谢这里的几十篇其他帖子!
节点基类用JsonConverter 装饰
[JsonObject( IsReference = true, TypeNameHandling = TypeNameHandling.All )]
[JsonConverter( typeof( ChainNodeConverter ))]
public abstract class Node
{
public List< Node > Children { get; set; }
}
ErrorNode类具有一些属性来帮助识别/恢复故障节点
public class ErrorNode : Node
{
public JToken JToken { get; set; }
public string FailedTypeString { get; set; }
}
节点转换器类
public class NodeConverter : JsonConverter
{
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return false; } }
public override bool CanConvert( Type objectType ) { return typeof( Node ).IsAssignableFrom( objectType ); }
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer )
{
throw new NotImplementedException("If CanWrite is false; this won't be called.");
}
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
var jToken = JToken.ReadFrom( reader );
var refString = jToken.Value< string >( "$ref" );
var firstReference = refString == null;
if ( firstReference )
{
var typeString = jToken.Value<string>( "$type" );
if ( typeString != null )
{
var type = Type.GetType( typeString );
if ( type == null )
{
var errorNode = new ErrorNode();
errorNode.JToken = jToken;
errorNode.FailedTypeString = typeString;
// Apply the old node's relationships to errorNode
serializer.Populate( jToken.CreateReader(), errorNode );
return errorNode;
}
}
}
// Default-like behaviour
return serializer.Deserialize( jToken.CreateReader() );
}
}