在 ASP.NET Core 2.1 Web API 中实现分页
Posted
技术标签:
【中文标题】在 ASP.NET Core 2.1 Web API 中实现分页【英文标题】:Implement Pagination in ASP.NET Core 2.1 Web API 【发布时间】:2019-02-19 05:28:50 【问题描述】:我搜索了,但并没有真正找到关于如何在 ASP.NET WebAPI Core 2.1 应用程序中实现分页逻辑的文章...
我有以下
[Route("api/[controller]")]
[ApiController]
[EnableCors("AllowMyOrigin")]
public class EntriesController : ControllerBase
private readonly EntriesContext _context;
public EntriesController(EntriesContext context)
_context = context;
if (_context.Entries.Count() == 0)
_context.Entries.Add(new Entry From = "default", To = "default" );
_context.SaveChanges();
[HttpGet]
public ActionResult<List<Entry>> GetAll()
return _context.Entries.ToList();
[HttpGet("id", Name = "GetEntry")]
public ActionResult<Entry> GetById(long id)
var item = _context.Entries.Find(id);
if (item == null) return NotFound();
return item;
现在,我希望使用新参数 page
和 pageSize
对我的条目进行分页。说
/api/entries?pageSize=3&page=2
我应该通过添加一些 http 参数来使用 GetAll()
方法,还是创建一个新方法?没有pageSize
,使用page
没有多大意义,我该如何管理?
【问题讨论】:
【参考方案1】:首先,您可以将pageSize
的值默认为某个值:
[HttpGet]
public ActionResult<List<Entry>> GetAll(int? page = null, int? pageSize = 10)
if (!page.HasValue)
return _context.Entries.ToList();
// do you pagination here
但你也可以看看OData,这似乎是你的情况。它将允许您使用 http 参数查询您的数据,例如:/api/Entires?$skip=5&$top=5
【讨论】:
OData 不可用,因为我了解 .NET Core 2.1 ?它似乎在 2.1 中被破坏了...github.com/OData/WebApi/issues/1447 @Serge 它应该可以正常工作,尽管它可能有一些问题。还提供问题已关闭 我建议不要使用 OData。许多大公司已经放弃了它的使用,例如 Netflix。甚至微软也在质疑它的未来。它是一项真正难以取得进展的专有技术。 Tx,您知道在 ASP.NET Core(带有 EF Core)和基于 .NET Standard 的客户端(Uno 平台)中是否有一个像样的 OData 服务器端 + 客户端? 【参考方案2】:有一些库,例如X.PagedList 可以使用。坦率地说,分页非常简单,所以你甚至可能不需要它。您只需要知道页码、页面大小和结果总数。页码显然来自请求,如果您希望它可以自定义,或者您可以对其进行硬编码,页面大小也可以。
public ActionResult<List<Entry>> GetAll(int page = 1, int size = 10)
然后,您可以使用Skip
和Take
来获取特定页面的数据:
var query = _context.Entries;
var entries = await query.Skip((page - 1) * size).Take(size).ToListAsync();
var count = await query.CountAsync();
那么,您只需要知道总页数,可以通过以下方式简单计算:
var totalPages = (int)Math.Ceil(count / (float)size);
由此,您可以计算出您需要的任何其他内容,即:
var firstPage = 1; // obviously
var lastPage = totalPages;
var prevPage = page > firstPage ? page - 1 : firstPage;
var nextPage = page < lastPage ? page + 1 : lastPage;
【讨论】:
我认为你可以用await Task.WhenAll(people, count);
等待entries
和count
而不是依次等待?
@koral,DbContext 不是线程安全的,所以你会得到一个异常【参考方案3】:
我刚刚为 ASP.NET Core Razor 页面创建了一个 PagingTagHelper,只需基本参数即可轻松呈现分页控件,最简单的设置如下所示:
<paging total-records="Model.TotalRecords" page-no="Model.PageNo">
</paging>
您只需要提供总记录和页码即可运行。默认的查询字符串参数是“p”表示页码,“s”表示页面大小,但是,它是可自定义/可本地化的,您可以根据自己的要求更改所有设置。
您可以从 nuget 安装它:
Install-Package LazZiya.TagHelpers -Version 1.0.2
那么你需要将标签助手添加到_ViewImports.cshtml文件中:
@addTagHelper *, LazZiya.TagHelpers
http://ziyad.info/en/articles/21-Paging_TagHelper_for_ASP_NET_Core
更多文档和现场演示即将推出。
【讨论】:
以上是关于在 ASP.NET Core 2.1 Web API 中实现分页的主要内容,如果未能解决你的问题,请参考以下文章
Asp.net core 2.1 Web App 无法在 IIS 上正确呈现
在 ASP.NET Core 2.1 Web 客户端中存储不记名令牌的位置
如何在 asp.net core 2.1 中使用 net.tcp 服务
ASP.NET Core 2.1 MVC - 无法设置从 Web api 响应接收到的 cookie
如何使用 fetch 将 FormData 从 javascript 发送到 ASP.NET Core 2.1 Web API