的集合時,我負責維護一個遊戲系統,用戶堅持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