Десериализация коллекции объектов JSON

268
14 апреля 2017, 19:02

Есть базовый класс и несколько его потомков:

class Base {...}
class A : Base {...}
class B : Base {...}

И коллекция этих объектов:

ObservableCollection<Base> Actions {get;set;}

В интерфейсной части для каждого типа объектов определен свой DataTemplate, но после выполнения десериализация все объекты коллекции апкастятся до Base и не отображают заданный шаблон.

Сериализация производится в Json с помощью библиотеки от Newtonsoft:

public static void Serialize(string path, object savedObject)
{
    var json = JsonConvert.SerializeObject(savedObject);
    using (var fs = new FileStream(path, FileMode.Create))
    {
        byte[] array = System.Text.Encoding.UTF8.GetBytes(json);
        fs.Write(array, 0, array.Length);
    }
}
public static object Deserialize(string path, Type type)
{
   string json = File.ReadAllText(path);
   return JsonConvert.DeserializeObject(json, type);
}

Как исправить это?

Answer 1
class Base {...}
class A : Base {...}
class B : Base {...}
var list = new List<Base>() 
{
   new A(), 
   new B()
}
var settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All
};
var json = JsonConvert.SerializeObject(list, settings);
var obj = JsonConvert.DeserializeObject<List<Base>>(json, settings);
Answer 2

Помог ответ с английского SO:

Нужно включить типы в сериализацию с помощью TypeNameHandling. В итоге методы преобразовались следующим образом:

public static void JsonSerialize(string path, object savedObject)
{
    JsonSerializerSettings settings = new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All
    };
    var json = JsonConvert.SerializeObject(savedObject, settings);
    using (var fs = new FileStream(path, FileMode.Create))
    {
        byte[] array = System.Text.Encoding.UTF8.GetBytes(json);
        fs.Write(array, 0, array.Length);
    }
}
public static object JsonDeserialize(string path, Type type)
{
    JsonSerializerSettings settings = new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All
    };
    string json = File.ReadAllText(path);
   return JsonConvert.DeserializeObject(json, type, settings);
}
READ ALSO
Загрузить DataTable в файл Excel по частям. C#, ASP.NET

Загрузить DataTable в файл Excel по частям. C#, ASP.NET

Я использую ClosedXMLExcel для создания файла Excel из DataTable

314
Отследить изменение свойств объекта

Отследить изменение свойств объекта

Есть коллекция вида ObservableCollection<BaseClass> Project {get;set;}

269
Скрыть panel если курсор за ее пределами

Скрыть panel если курсор за ее пределами

Panel1 открывается по нажатию на buttonНужно чтобы panel1 скрылась когда курсор выходит за ее границы

252