的集合时,我负责维护一个游戏系统,用户坚持JSON序列波苏斯在本地缓存中保存的,例如,一个Character
状态失败。反序列化反序列化接口
代码的最新版本已改变这些序列化对象的数据模型。特别是,创建了一个新的界面。这是在将旧的字符反序列化为新代码时产生的问题。我试图用自定义转换器来解决这些问题,但我遇到了麻烦。
老,系列化的版本:
public class Character{
public Skill Parent {get;set;}
public Dictionary<string,Skill} Skills {get;set;}
}
public class Skill {
//normal stuff here.
}
新版本:
public class Character{
[JsonProperty, JsonConverter(typeof(ConcreteTypeConverter<Dictionary<string,Skill>>))]
public Dictionary<string,ISkill} Skills {get;set;}
}
public class Skill:ISkill {
//normal stuff here.
}
public interface ISkill{
//stuff that all skill-like things have here
}
但我仍然遇到麻烦反序列化收集。
public class Extensions
{
//a lot of serializer extensions here including the Deserialize method
private static readonly CustomSerializationBinder Binder = new CustomSerializationBinder();
private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
TypeNameHandling = TypeNameHandling.Objects,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple,
Binder = Binder,
};
}
public class CustomSerializationBinder : DefaultSerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
return base.BindToType(assemblyName, typeName);
}
}
public class ConcreteTypeConverter<T> : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer,value); // serialization isnt't the problem.
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (typeof (T)==typeof(Dictionary<string,Skill>))
{
var retVal = new object();
if (reader.TokenType == JsonToken.StartObject)
{
T instance = (T)serializer.Deserialize(reader, typeof(T)); //crashes here
retVal = new List<T>() { instance };
return retVal;
}
}
return serializer.Deserialize<T>(reader);
}
public override bool CanConvert(Type objectType)
{
return true; // kind of a hack
}
}
所以我有一个老Dictionary<string,Skill>
,我不能投,要Dictionary<string,ISkill>
中,我可以看到任何代码路径。我应该如何解决这个问题?
看看https://stackoverflow.com/questions/33321698/jsonconverter-with-interface。这给出了一个通用转换器,通过使用'$ type'(如果存在)或者如果不存在,选择最佳属性匹配,将确定哪个具体的'Skill'类为'ISkill'接口反序列化。 – dbc
我会看看。我已经使用'$ type'来解决一些问题(以膨胀为代价),所以也许这是一个很好的前进方向。 我担心的是,陈旧的JSON都将有一个'$ type'这是'Skill',不'ISkill'问题 - 还有,如何处理'$ type'这是'词典<字符串,技能>'。 – gvoysey
我不是100%确定我理解你的问题。您的遗留JSON(从“Skill”到“ISkill”重构之前)是否包含字典本身的“$ type”信息? – dbc