序列化/反序列化IPagedList< T>使用JSON.NET

本文关键字:使用 JSON NET 反序列化 IPagedList 序列化 | 更新日期: 2023-09-27 18:13:25

我有以下用例,我想序列化/反序列化我的IPagedList的T使用JSON.net (Newtonsoft.Json)。这似乎不起作用。它不序列化所有内容,只序列化项(或者使用我自己的ContractResolver,即具有空属性的对象)。我正在使用X.PagedList nuget。

测试用例:

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);
}

那么我怎样才能成功地序列化/反序列化这个类呢?

序列化/反序列化IPagedList< T>使用JSON.NET

当你序列化IPagedList时,它序列化请求页面的内容/数据,而不是元数据(即firsttemonpage, HasNextPage等属性)将丢失。为了解决这个问题,你可以创建一个像下面这样的匿名类,它有两个属性

  • items保存当前页面内容
  • metaData保存超级列表元数据。

因此将代码的第一部分更改为:

 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类封装元数据,这样当我们反序列化子列表时,它的元数据将被反序列化为这种类型。

  • PaginationEntityClass where T: class class封装匿名类,这样当我们反序列化子列表时,它的内容和元数据将被反序列化为这种类型

  • PaginationEntityStruct where T: struct与PaginationEntityClass相同,但这里的T是一个结构体,因此它保存结构体类型而不是像int那样的类。

所以这三个类如下:

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);

也许你可以考虑使用内置的LINQ函数.skip() &.take() .

根据我上面的评论,PagedList的repo似乎已经很久没有维护了。在你头撞到墙上之前,不妨试试上面的内置函数。

PagedList . github . repo.

Skip &把