Как десериализовать полиморфные коллекции в JsonFX?
Мой код сериализации JsonFX работает, но объект, который я сериализую, содержит список полиморфных сущностей, и все они десериализованы как их базовый тип, а не их фактический тип.
Вот мой код сериализации:
public static string Serialize(System.Object obj)
{
StringBuilder builder = new StringBuilder();
using (TextWriter textWriter = new StringWriter(builder))
{
JsonWriter writer = new JsonWriter(textWriter);
writer.Write(obj);
return builder.ToString();
}
}
public static T Deserialize<T>(string json)
{
using (TextReader textReader = new StringReader(json))
{
var jsonReader = new JsonReader(textReader);
return jsonReader.Deserialize<T>();
}
}
Как видите, это довольно просто. Я также не украшаю свои классы какими-либо атрибутами или чем-то особенным, чтобы сделать их сериализуемыми. Помимо полиморфной проблемы, кажется, что все работает правильно.
Так как я могу заставить мои полиморфные типы правильно десериализоваться?
Благодарю.
1 ответ
Вам нужно включить подсказку типа. Вот пример кода (это относится к JsonFx v1.4, может работать или не работать с вашей версией):
StringBuilder result = new StringBuilder(string.Empty);
JsonWriterSettings settings = JsonDataWriter.CreateSettings(true);
settings.TypeHintName = "__type";
JsonWriter writer = new JsonWriter(result, settings);
writer.Write(obj);
return result.ToString();
Это добавит дополнительные данные в вашу строку JSON, которая выглядит примерно так:
"__type": "MyNamespace.MyClass, MyAssembly",
Это означает, что он выясняет, какой производный тип основан на имени класса. Если вы измените имя класса или имя пространства имен, оно больше не будет работать. Хуже того, вы больше не сможете десериализовать из своих старых текстовых данных JSON, если не будете массово заменять все вхождения старого имени класса и заменять его новым.
Поэтому вы должны быть осторожны с этим.
РЕДАКТИРОВАТЬ: Забыл упомянуть, что вы должны отредактировать исходный код JsonFx, чтобы это работало. В JsonReader.cs найдите метод ReadArray:
Изменить:
object value = this.Read(arrayItemType, isArrayTypeAHint);
чтобы:
object value = this.Read(null, false);
Это гарантирует, что JsonFx всегда будет пытаться выяснить тип каждого элемента в массиве / списке. Если вы хотите, чтобы это работало только для отдельных переменных, вам нужно внести изменения в соответствующий код (еще не пробовал).