我有以下用例,我想序列化/反序列化我的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时,它序列化请求页面的内容/数据,而不是元数据(即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 &把