向 IQueryable 添加扩展方法,该方法对列表进行分页并在从 API 控制器方法返回时返回 json 对象

Posted

技术标签:

【中文标题】向 IQueryable 添加扩展方法,该方法对列表进行分页并在从 API 控制器方法返回时返回 json 对象【英文标题】:Add extension method to IQueryable which paginates list and returns json object when returned from a API Controller method 【发布时间】:2022-01-22 21:26:29 【问题描述】:

你好我有一个扩展方法如下

public static PaginatedList<T> Paginate(this IQueryable<T> queryable, int page, int PerPage) where T : class 
   var total = queryable.Count();
   var list = queryable.Skip(Page * perPage).Take(perPage).ToList();
   return new PaginatedList<T>(list, total, perPage, page);


public class PaginatedList<T> : List<T> where T : class 
   public int PerPage get;
   public int Total get;;
   public int CurrentPage get;
   public PaginatedList(IList<T> list, int total, int perPage, int currentPage) 
    PerPage = perPage;
    Total = total;
    CurrentPage = currentPage;
    this.AddRange(list);
   

在我的控制器中,我有一个 API 获取方法

[HttpGet]
public PaginatedList<Site> Get() 
  return dbContext.Sites.Paginate(0, 15);

列表 API 返回列表,但是我想将响应返回为

 
  perPage: 15, 
  total: 100,
  currentPage: 1,
  items: []
 

我尝试过实现 JsonConverter 和其他序列化。但是我找不到告诉 .NET Core 在返回 PaginatedList 类的响应时使用我希望它使用的格式的方法。

【问题讨论】:

您的 PaginatedList 类中没有 currentPage 属性,添加它并查看输出。还有,前面用什么来检索? 是的,我已经添加了。问题不在于财产。当前响应发送对象列表,如 [, ]。但是对于我的场景,我想要一个具有 PaginatedList 属性的对象和 item 是列表的其他项目。为此,我猜应该有.netcore提供的接口。我根本无法弄清楚那是什么。我只是从 javascript 调用端点 [url]/api/sites 来检索它。 【参考方案1】:

这里的主要问题是你在课堂上使用了inheritance,实际上你必须使用composition

让我澄清一下,在您当前的实现中,您继承自 List&lt;T&gt; 因此,当您向类添加属性时,实际上是将这些属性添加到列表中,但是,除了其他属性之外,您只需要将列表作为类中的属性。 所以你可以改变你的班级如下:

public class PaginatedList<T> where T : class 
   public IList<T> List  get;
   public int PerPage get;
   public int Total get;;
   public int CurrentPage get;
   public PaginatedList(IList<T> list, int total, int perPage, int currentPage) 
    List = list
    PerPage = perPage;
    Total = total;
    CurrentPage = currentPage;
   

【讨论】:

对不起。我的错。我已经在我的实际代码中返回了 PaginatedList 类的实例。我错过了将那段代码放在问题中。我刚刚编辑了它。我正在寻找类似接口的方法来创建我的自定义响应。 是的,我明白了。您是否使用 swagger ui 或 postman 测试了返回的响应?也尝试将 Get 方法的类型更改为 IActionResult 并返回 `Ok(dbContext.Sites.Paginate(0, 15)) 我在 Swagger UI 中测试响应。我尝试将返回类型更改为 IActionResult 并返回 Ok(dbContext.Sites.Paginate(0,15))。这将返回数组列表。当然,它会这样做吗?因为我没有编写可以自定义 [obj].Paginate() 方法输出的部分。我正在寻找一种方法,当它尝试为 dBcontext.Sites.Paginate() 创建响应时,我可以告诉 .net 核心使用我的自定义响应代码块 是的,我已经意识到问题出在哪里。我已经更新了我的答案。希望对你有帮助 是的,您的解决方案解决了我的问题。但是,我继承 List 类的原因是我希望我的 PaginatedList 也是可迭代的。为此,要么我必须从列表继承,要么我必须实现 IEnumerable。如果我不实施 IEnumerable 解决方案工作正常。但是,在实现 IEnumerable 之后,结果响应仍然是相同的旧列表。这就是为什么我试图找出是否有一种方法可以覆盖或实现来操作生成的 json。我对您的解决方案竖起大拇指,因为这是实现我想要的结果的一种方法。

以上是关于向 IQueryable 添加扩展方法,该方法对列表进行分页并在从 API 控制器方法返回时返回 json 对象的主要内容,如果未能解决你的问题,请参考以下文章

IQueryable vs IEnumerable ...扩展方法

使用 LINQ 的 IQueryable 左外连接的扩展方法

使用IQueryable扩展方法实现复杂查询条件

具有不同属性传递动态表达式的IQueryable扩展方法

如何使用通用扩展方法中的字符串列名在 IQueryable 上应用 OrderBy?

将 IQueryable 与 Linq 一起使用