【问题标题】:Serialize/deserialize IPagedList<T> using JSON.NET使用 JSON.NET 序列化/反序列化 IPagedList<T>
【发布时间】:2017-02-27 08:09:05
【问题描述】:

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

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

【问题讨论】:

  • 您是否通过调试确认paged包含数据?
  • 是的,它包含了我期望的所有数据,IsLastPage、PageSize、HasNextPage 等都设置好了。
  • PagedList github repo 好像不再维护了。最好按照我在下面的建议使用内置函数,这样发生意外行为的可能性较小。
  • 我正在使用 x.PagedList,它是 PagedList 的一个分支,似乎得到了维护。但我想使用这个 nuget 的原因是它可以轻松快速地创建网格页面。

标签: c# json serialization json.net


【解决方案1】:

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

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

PagedList github repo.

Samples for Skip & Take

【讨论】:

    【解决方案2】:

    当您序列化 IPagedList 时,它会序列化请求页面的内容/数据,而不会丢失元数据(即 FirstItemOnPage、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 类来封装匿名类,因此当我们反序列化子列表时,其内容和元数据将反序列化为此类型。

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

    【讨论】:

      猜你喜欢
      • 2017-01-15
      • 1970-01-01
      • 2015-10-25
      • 2012-04-09
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 2015-11-22
      相关资源
      最近更新 更多