2016-10-18 3 views
0

У меня есть следующий прецедент, я хочу сериализовать/десериализовать свой IPagedList T с помощью JSON.net (Newtonsoft.Json). Кажется, это не работает. Он не сериализует все, только элементы (или мой собственный ContractResolver, объект с пустыми свойствами). Я использую X.PagedList nuget.Сериализация/десериализация IPagedList <T> с использованием JSON.NET

Тестовый пример:

var list = new List<int>(Enumerable.Range(1, 1000)); 
var paged = list.AsQueryable().ToPagedList(3, 10); 


var json = JsonConvert.SerializeObject(paged); (output: [21,22,23,24,25,26,27,28,29,30]) 
var obj = JsonConvert.DeserializeObject<PagedList<int>>(json); 

Когда я продлить DefaultContractResolver и переопределить метод CreateContract, он десериализует к объекту IPagedList но никаких свойств не заполнено, а также никаких пунктов .. я пытался переопределить CreateProperties но это не сработало, как я ожидал.

protected override JsonContract CreateContract(Type objectType) 
{ 
    if (typeof(IPagedList).IsAssignableFrom(objectType)) 
    { 
     return CreateObjectContract(objectType); 
    } 
    return base.CreateContract(objectType); 
} 

Итак, как я могу успешно сериализовать/десериализовать этот класс?

+0

Вы подтвердили, что 'paged' содержит данные с помощью отладки? –

+0

Да, он содержит все данные, которые я ожидаю, IsLastPage, PageSize, HasNextPage и т. Д. Все установлены. – ronaldm

+0

Кажется, что pagingList github repo больше не поддерживается. Лучше всего использовать встроенные функции согласно моему предложению ниже, где вероятность появления неожиданного поведения меньше. –

ответ

0

Возможно, вы можете использовать встроенные функции LINQ .skip() & .take().

Как и в моем комментарии выше, кажется, что репо для PagedList не поддерживается в течение длительного времени. Прежде чем постучать головой о стену, попробуйте выполнить вышеперечисленные функции.

PagedList github repo.

Samples for Skip & Take

-2

При сериализации IPagedList он упорядочивает содержимое/данные из запрашиваемой страницы, а не мета-данные (т.е. FirstItemOnPage, HasNextPage и т.д. свойства) будут потеряны. Так, чтобы преодолеть эту проблему, вы можете создать анонимный класс как следующий, который будет иметь два свойства

  • элементы держит текущее содержимое страницы
  • МЕТАДАННЫХ держит супер метаданные списка.

Меняет первую часть вашего кода:

var list = new List<int>(Enumerable.Range(1, 1000)); 
var paged = list.AsQueryable().ToPagedList(3, 10); 
var pagedWithMetaData = new { items = paged, metaData = paged.GetMetaData() }; 

затем сериализации, что объект

//Serialize 
var json = JsonConvert.SerializeObject(pagedWithMetaData); 

Это создаст суб-список с метаданными для вашего примера походит на следующем :

{"items":[21,22,23,24,25,26,27,28,29,30],"metaData":{"PageCount":100,"TotalItemCount":1000,"PageNumber":3,"PageSize":10,"HasPreviousPage":true,"HasNextPage":true,"IsFirstPage":false,"IsLastPage":false,"FirstItemOnPage":21,"LastItemOnPage":30}} 

Теперь для десериализации вам необходимо создать три класса:

  • PaginationMetaData класс инкапсулирует метаданные таким образом, когда мы десериализации список суб это метаданные будут deserialzed к этому типу.

  • PaginationEntityClass где T: класс класс инкапсулировать анонимный класс так, когда мы десериализация списка вложенного его содержания и метаданных будет deserialzed к этому типу.

  • PaginationEntityStruct где T: STRUCT же, как PaginationEntityClass но Т здесь является структурой, так что держать типов структуры вместо классов, как ваш случай для междунар.

Таким образом, эти три класса будет следующим:

public class PaginationMetaData 
{ 
    public int FirstItemOnPage { get; set; } 
    public bool HasNextPage { get; set; } 
    public bool HasPreviousPage { get; set; } 
    public bool IsFirstPage { get; set; } 
    public bool IsLastPage { get; set; } 
    public int LastItemOnPage { get; set; } 
    public int PageCount { get; set; } 
    public int PageNumber { get; set; } 
    public int PageSize { get; set; } 
    public int TotalItemCount { get; set; } 
} 

public class PaginationEntityClass<T> where T : class 
{ 
    public PaginationEntityClass() 
    { 
     Items = new List<T>(); 
    } 
    public IEnumerable<T> Items { get; set; } 
    public PaginationMetaData MetaData { get; set; } 
} 

public class PaginationEntityStruct<T> where T : struct 
{ 
    public PaginationEntityStruct() 
    { 
     Items = new List<T>(); 
    } 
    public IEnumerable<T> Items { get; set; } 
    public PaginationMetaData MetaData { get; set; } 
} 

Теперь десериализовать вам нужно просто десериализовать к PaginationEntityStruct из числа затем использовать второй конструктор перегрузки класса StaticPagedList (класс поставляется с пакетом PagedList) для воссоздания подкласса с метаданными.

//Deserialize 
var result = JsonConvert.DeserializeObject<PaginationEntityStruct<int>>(json); 
StaticPagedList<int> lst = new StaticPagedList<int>(
        result.Items, 
        result.MetaData.PageNumber, 
        result.MetaData.PageSize, 
        result.MetaData.TotalItemCount); 
Смежные вопросы