Я не могу десериализовать коллекцию элементов, где экземпляры имеют отношения наследования между ними.
Кто-нибудь сталкивался с этой проблемой?
Итак, мой вариант использования такой:
Моя модель похожа на это:
[DataContract]
public class Item
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public bool Valid { get; set; }
}
[DataContract]
public class IntermediateItem : Item
{
[DataMember]
public int Priority { get; set; }
}
[DataContract]
public class ExtendedItem : IntermediateItem
{
[DataMember]
public int Count { get; set; }
[DataMember]
public ItemsCollection Childs { get; set; }
}
И коллекция предметов выглядит примерно так:
[DataContract]
public class ItemsCollection : Collection<Item>
{
}
Настройка, которую я сделал для обеспечения правильной десериализации:
Определение CollectionFormatterBase:
public class ItemCollectionFormatterBase : CollectionFormatterBase<Item, ItemsCollection>
{
protected override ItemsCollection Create(int count)
{
return new ItemsCollection();
}
protected override void Add(ItemsCollection collection, int index, Item value)
{
collection.Add(value);
}
}
Пример, который не работает и не работает. Я имею в виду, что десериализованные экземпляры имеют базовый тип, то есть как наследование потеряно при сериализации.
Пример:
MessagePack.Resolvers.CompositeResolver.RegisterAndSetAsDefault(new[] { new ItemCollectionFormatterBase() }, new[] { StandardResolver.Instance });
ExtendedItem instance = new ExtendedItem()
{
Id = 1,
Name = "Extended Item",
Priority = 121,
Valid = true,
Count = 10,
Childs = new ItemsCollection(new List<Item>() { new Item() { Id = 1 }, new IntermediateItem() { Priority = 10 }, new ExtendedItem() { Count = 10 } })
};
byte[] bytes = MessagePackSerializer.Serialize(instance);
using (FileStream file = new FileStream(this.filePath.AbsolutePath, FileMode.Create))
{
await file.WriteAsync(bytes , 0, payload.Length);
await file.FlushAsync();
}
using (FileStream file = new FileStream(testsFolder + @"\ExtendedItem.msgPack-csharp.dat", FileMode.Open))
{
file.Seek(0, SeekOrigin.Begin);
deserializedInstance = MessagePackSerializer.Deserialize<ExtendedItem>(file);
}
глядя на дочерние элементы deserializedInstance, все они относятся к типу элемента.
Можете ли вы сказать мне, что я делаю не так? Чего не хватает?
Небольшое обновление относительно определения предмета:
[DataContract]
[KnownType(typeof(IntermediateItem))]
[KnownType(typeof(ExtendedItem))]
public class Item
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public bool Valid { get; set; }
}
Это тоже не работает. (