使用JSON.NET对IPagedList <t>进行序列化/反序列化

时间:2016-10-18 07:05:33

标签: c# json serialization json.net

我有以下用例,我想使用JSON.net(Newtonsoft.Json)序列化/反序列化我的TagedList of T。这似乎不起作用。它不会序列化所有内容,只会序列化项目(或者使用我自己的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);
}

那么如何成功序列化/反序列化这个类?

2 个答案:

答案 0 :(得分:0)

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

根据我上面的评论,似乎PagedList的回购在很长一段时间内都没有得到维护。在将头撞到墙上之前,可以尝试上面的内置功能。<​​/ p>

PagedList github repo.

Samples for Skip & Take

答案 1 :(得分:0)

当您序列化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);

这将为您的示例生成一个包含metaData的子列表,如下所示:

{"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,其中T:class 类封装匿名类,因此当我们反序列化子列表时,其内容和元数据将被反序列化为此类型。

  • PaginationEntityStruct,其中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);