[英]How to implement pagination in asp.net core razor pages
I'm learning asp.net core razor pages with ef.我正在使用 ef 学习 asp.net 核心剃刀页面。 I want to implement pagination with my table, I have check this tutorial
我想用我的表实现分页,我已经检查了这个教程
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-2.1 https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-2.1
but it only support pre and next, I have researched for a long time, all of the solution are related to asp.net core mvc, but I'm using razor pages, there's no controller in my project, any ideas to implement?但它只支持pre和next,我研究了很长时间,所有解决方案都与asp.net core mvc有关,但我使用的是razor pages,我的项目中没有控制器,有什么想法可以实现吗?
This is the effect what I want to implement这是我想要实现的效果
<form method="get" asp-page="./Index">
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
@{
var totalPages = Model.Products.Count % 2 == 0 ? Model.Products.Count / 2 : Model.Products.Count / 2 + 1;
}
@for (int i = 1; i <= totalPages; i++)
{
<li><a asp-page="./Index" asp-route-id="@i">@i</a></li>
}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</form>
cshtml.cs cshtml.cs
public async Task OnGetAsync(string sortOrder, string searchString, string shopString, string statusString, int page)
{}
Pagination is relatively simple.分页比较简单。 There's libraries available to do it for you, but I've started to find them more trouble than they're worth.
有一些库可以为你做这件事,但我开始发现它们比它们的价值更麻烦。
You need three pieces of information from the request (or set to default values):您需要来自请求的三条信息(或设置为默认值):
The page number and size give you your "skip" and "take" values:页码和大小为您提供“跳过”和“获取”值:
var skip = (page - 1) * size;
var take = size;
You can then fetch the results via:然后您可以通过以下方式获取结果:
var pageOfResults = await query.Skip(skip).Take(take).ToListAsync();
Where query
is an IQueryable
- either your DbSet
directly or the DbSet
with a Where
clause, OrderBy
, etc. applied.其中
query
是一个IQueryable
- 直接使用DbSet
或应用了Where
子句、 OrderBy
等的DbSet
。
Then, you just need to the total number of items to figure the pages:然后,您只需要通过项目总数来计算页面:
var count = await query.CountAsync();
Pro Tip , you can parallelize the two queries (results and total count) by doing:专业提示,您可以通过执行以下操作并行化两个查询(结果和总计数):
var resultsTask = query.Skip(skip).Take(take).ToListAsync();
var countTask = query.CountAsync();
var results = await resultsTask;
var count = await countTask;
Tasks return hot, or already started.任务返回热,或已经开始。 The
await
keyword simply holds the continuation of the rest of the code until the task completes. await
关键字只是保持其余代码的继续,直到任务完成。 As a result, if you await each line, they'll complete in serial, but if you start both, first, and then await each, they'll process in parallel.因此,如果您等待每一行,它们将串行完成,但如果您先启动两条线,然后等待每条线,它们将并行处理。
Anyways, once you have the count:无论如何,一旦你有了计数:
var totalPages = (int)Math.Ceil(Decimal.Divide(count, size));
var firstPage = 1;
var lastPage = totalPages;
var prevPage = Math.Max(page - 1, firstPage);
var nextPage = Math.Min(page + 1, lastPage);
Note: you can determine whether to show first/previous and last/next buttons based on whether they equal firstPage
or lastPage
, respectively.注意:您可以根据是否分别等于
firstPage
或lastPage
来确定是否显示第一个/上一个和最后一个/下一个按钮。
Then, just build yourself a model with this information, and you can send that to the view to render the results and generate the paging HTML.然后,只需使用此信息为自己构建一个模型,您就可以将其发送到视图以呈现结果并生成分页 HTML。
I have created a paging taghelper for .net Core Razor Pages, it can be configured within html tags or appsettings.json to show/ hide prev-next, first-last buttons, number of max displayed pages and more customization settings are available,我为 .net Core Razor 页面创建了一个分页标签助手,它可以在 html 标签或 appsettings.json 中配置以显示/隐藏上一个下一个、第一个最后一个按钮、最大显示页面数和更多自定义设置可用,
Install the nuget package:安装 nuget 包:
Install-Package LazZiya.TagHelpers
Add the taghelper to _ViewImports.cshtml将 taghelper 添加到 _ViewImports.cshtml
@addTagHelper *, LazZiya.TagHelpers
Finally add the paging control to the view:最后在视图中添加分页控件:
<paging
total-records="Model.TotalRecords"
page-no="Model.PageNo"
query-string-value="@(Request.QueryString.Value)">
</paging>
Starting from v3.1.0 query-string-value
is not necessary to be passed, additonally all options is turned on by default.从 v3.1.0 开始不需要传递
query-string-value
,另外所有选项默认开启。
<paging
total-records="Model.TotalRecords"
page-no="Model.PageNo">
</paging>
Using appsettings.json for paging configurations will help to have more clean html code and it gives the ability to change paging settings on all or some paging taghelpers by once in the application.使用 appsettings.json 进行分页配置将有助于获得更干净的 html 代码,并且可以在应用程序中一次性更改所有或某些分页标签助手的分页设置。
See live demo for all settings: http://demo.ziyad.info/en/paging查看所有设置的现场演示: http : //demo.ziyad.info/en/paging
Related article: http://ziyad.info/en/articles/21-Paging_TagHelper_for_ASP_NET_Core相关文章:http: //ziyad.info/en/articles/21-Paging_TagHelper_for_ASP_NET_Core
You can use the JW.Pager
NuGet package ( https://www.nuget.org/packages/JW.Pager/ )您可以使用
JW.Pager
NuGet 包 ( https://www.nuget.org/packages/JW.Pager/ )
Here's an example razor pages page model that paginates a list of 150 items:这是一个示例 razor pages 页面模型,它对 150 个项目的列表进行分页:
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.RazorPages;
using JW;
namespace RazorPagesPagination.Pages
{
public class IndexModel : PageModel
{
public IEnumerable<string> Items { get; set; }
public Pager Pager { get; set; }
public void OnGet(int p = 1)
{
// generate list of sample items to be paged
var dummyItems = Enumerable.Range(1, 150).Select(x => "Item " + x);
// get pagination info for the current page
Pager = new Pager(dummyItems.Count(), p);
// assign the current page of items to the Items property
Items = dummyItems.Skip((Pager.CurrentPage - 1) * Pager.PageSize).Take(Pager.PageSize);
}
}
}
And here's the razor pages page containing the html for the paged list and pager controls:这是包含分页列表和寻呼机控件的 html 的 razor 页面:
@page
@model RazorPagesPagination.Pages.IndexModel
<!-- items being paged -->
<table class="table table-sm table-striped table-bordered">
@foreach (var item in Model.Items)
{
<tr>
<td>@item</td>
</tr>
}
</table>
<!-- pager -->
@if (Model.Pager.Pages.Any())
{
<nav class="table-responsive">
<ul class="pagination justify-content-center d-flex flex-wrap">
@if (Model.Pager.CurrentPage > 1)
{
<li class="page-item">
<a class="page-link" href="/">First</a>
</li>
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.CurrentPage - 1)">Previous</a>
</li>
}
@foreach (var p in Model.Pager.Pages)
{
<li class="page-item @(p == Model.Pager.CurrentPage ? "active" : "")">
<a class="page-link" href="/?p=@p">@p</a>
</li>
}
@if (Model.Pager.CurrentPage < Model.Pager.TotalPages)
{
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.CurrentPage + 1)">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.TotalPages)">Last</a>
</li>
}
</ul>
</nav>
}
For more details I posted a full tutorial with example project at http://jasonwatmore.com/post/2018/10/15/aspnet-core-razor-pages-pagination-example有关更多详细信息,我在http://jasonwatmore.com/post/2018/10/15/aspnet-core-razor-pages-pagination-example 上发布了包含示例项目的完整教程
I made this implementation mixing together a few answers on the subject, I hope it helps someone.我将这个实现混合了一些关于这个主题的答案,我希望它对某人有所帮助。
Add a PagedResultBase
class (that you can extend adding other properties you need):添加一个
PagedResultBase
类(您可以扩展添加您需要的其他属性):
public abstract class PagedResultBase
{
public int CurrentPage { get; set; }
public int PageCount { get; set; }
public int PageSize { get; set; }
public int RowCount { get; set; }
}
Add a PagedResult
class:添加一个
PagedResult
类:
public class PagedResult<T> : PagedResultBase where T : class
{
public ICollection<T> Results { get; set; }
public PagedResult()
{
Results = new List<T>();
}
}
Add a IQueryableExtensions
with a GetPagedResult
extension:添加带有
GetPagedResult
扩展的IQueryableExtensions
:
public static class IQueryableExtensions
{
public async static Task<PagedResult<T>> GetPagedResultAsync<T>(this IQueryable<T> query, int currentPage, int pageSize) where T : class
{
var skip = (currentPage - 1) * pageSize;
var take = pageSize;
var rowCount = await query.CountAsync();
var results = await query.Skip(skip).Take(take).ToListAsync();
var pagedResult = new PagedResult<T> {
CurrentPage = currentPage,
PageCount = (int)Math.Ceiling(decimal.Divide(rowCount, pageSize)),
PageSize = pageSize,
RowCount = rowCount,
Results = results
};
return pagedResult;
}
}
You are done:你完成了:
var pagedResult = await MyContext.Posts.Where(p => p.Featured == true).GetPagedResultAsync(1, 10);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.