¿Cómo hago paginación en ASP.NET MVC?

¿Cuál es la forma más preferida y más fácil de hacer paginación en ASP.NET MVC? Es decir, ¿cuál es la forma más fácil de dividir una lista en varias páginas navegables?

Como ejemplo digamos que obtengo una lista de elementos de una base de datos / gateway / repository como este:

public ActionResult ListMyItems() { List list = ItemDB.GetListOfItems(); ViewData["ItemList"] = list; return View(); } 

En aras de la simplicidad, me gustaría especificar solo un número de página para mi acción como parámetro. Me gusta esto:

 public ActionResult ListMyItems(int page) { //... } 

Bueno, ¿cuál es la fuente de datos? Su acción podría tomar algunos argumentos predeterminados, es decir,

 ActionResult Search(string query, int startIndex, int pageSize) {...} 

predeterminado en la configuración de rutas para que startIndex sea 0 y pageSize sea (digamos) 20:

  routes.MapRoute("Search", "Search/{query}/{startIndex}", new { controller = "Home", action = "Search", startIndex = 0, pageSize = 20 }); 

Para dividir el feed, puede usar LINQ bastante fácilmente:

 var page = source.Skip(startIndex).Take(pageSize); 

(o haga una multiplicación si usa “pageNumber” en lugar de “startIndex”)

Con LINQ-toSQL, EF, etc., esto también debe “componerse” en la base de datos.

Debería poder usar enlaces de acción a la siguiente página (etc.):

 <%=Html.ActionLink("next page", "Search", new { query, startIndex = startIndex + pageSize, pageSize }) %> 

Tuve el mismo problema y encontré una solución muy elegante para una clase de buscapersonas de

http://blogs.taiga.nl/martijn/2008/08/27/paging-with-aspnet-mvc/

En su controlador, la llamada se ve así:

 return View(partnerList.ToPagedList(currentPageIndex, pageSize)); 

y en su opinión:

 
Seite: <%= Html.Pager(ViewData.Model.PageSize, ViewData.Model.PageNumber, ViewData.Model.TotalItemCount)%>

Quería cubrir una forma simple de hacer esto con la parte delantera también:

Controlador:

 public ActionResult Index(int page = 0) { const int PageSize = 3; // you can always do something more elegant to set this var count = this.dataSource.Count(); var data = this.dataSource.Skip(page * PageSize).Take(PageSize).ToList(); this.ViewBag.MaxPage = (count / PageSize) - (count % PageSize == 0 ? 1 : 0); this.ViewBag.Page = page; return this.View(data); } 

Ver:

 @* rest of file with view *@ @if (ViewBag.Page > 0) {  « Prev  } @if (ViewBag.Page < ViewBag.MaxPage) {  Next »  } 

Controlador

  [HttpGet] public async Task Index(int page =1) { if (page < 0 || page ==0 ) { page = 1; } int pageSize = 5; int totalPage = 0; int totalRecord = 0; BusinessLayer bll = new BusinessLayer(); MatchModel matchmodel = new MatchModel(); matchmodel.GetMatchList = bll.GetMatchCore(page, pageSize, out totalRecord, out totalPage); ViewBag.dbCount = totalPage; return View(matchmodel); } 

Lógica de negocios

  public List GetMatchCore(int page, int pageSize, out int totalRecord, out int totalPage) { SignalRDataContext db = new SignalRDataContext(); var query = new List(); totalRecord = db.Matches.Count(); totalPage = (totalRecord / pageSize) + ((totalRecord % pageSize) > 0 ? 1 : 0); query = db.Matches.OrderBy(a => a.QuestionID).Skip(((page - 1) * pageSize)).Take(pageSize).ToList(); return query; } 

Vista para mostrar el recuento total de páginas

  if (ViewBag.dbCount != null) { for (int i = 1; i <= ViewBag.dbCount; i++) { 
  • @Html.ActionLink(@i.ToString(), "Index", "Grid", new { page = @i },null)
} }

Creo que la forma más fácil de crear paginación en la aplicación ASP.NET MVC es utilizar la biblioteca PagedList.

Hay un ejemplo completo en seguir el repository de Github. Espero que ayude

 public class ProductController : Controller { public object Index(int? page) { var list = ItemDB.GetListOfItems(); var pageNumber = page ?? 1; var onePageOfItem = list.ToPagedList(pageNumber, 25); // will only contain 25 items max because of the pageSize ViewBag.onePageOfItem = onePageOfProducts; return View(); } } 

Enlace demo: http://ajaxpagination.azurewebsites.net/

Código fuente: https://github.com/ungleng/SimpleAjaxPagedListAndSearchMVC5

Entidad

 public class PageEntity { public int Page { get; set; } public string Class { get; set; } } public class Pagination { public List Pages { get; set; } public int Next { get; set; } public int Previous { get; set; } public string NextClass { get; set; } public string PreviousClass { get; set; } public bool Display { get; set; } public string Query { get; set; } } 

HTML

  

Lógica de búsqueda

 public Pagination GetCategoryPaging(int currentPage, int recordCount, string query) { string pageClass = string.Empty; int pageSize = 10, innerCount = 5; Pagination pagination = new Pagination(); pagination.Pages = new List(); pagination.Next = currentPage + 1; pagination.Previous = ((currentPage - 1) > 0) ? (currentPage - 1) : 1; pagination.Query = query; int totalPages = ((int)recordCount % pageSize) == 0 ? (int)recordCount / pageSize : (int)recordCount / pageSize + 1; int loopStart = 1, loopCount = 1; if ((currentPage - 2) > 0) { loopStart = (currentPage - 2); } for (int i = loopStart; i <= totalPages; i++) { pagination.Pages.Add(new PageEntity { Page = i, Class = string.Empty }); if (loopCount == innerCount) { break; } loopCount++; } if (totalPages <= innerCount) { pagination.PreviousClass = "disabled"; } foreach (var item in pagination.Pages.Where(x => x.Page == currentPage)) { item.Class = "active"; } if (pagination.Pages.Count() <= 1) { pagination.Display = false; } return pagination; } 

Usando el controlador

 public ActionResult GetPages() { int currentPage = 1; string search = string.Empty; if (!string.IsNullOrEmpty(Request.QueryString["page"])) { currentPage = Convert.ToInt32(Request.QueryString["page"]); } if (!string.IsNullOrEmpty(Request.QueryString["q"])) { search = "&q=" + Request.QueryString["q"]; } /* to be Fetched from database using count */ int recordCount = 100; Place place = new Place(); Pagination pagination = place.GetCategoryPaging(currentPage, recordCount, search); return PartialView("Controls/_Pagination", pagination); } 
 public ActionResult Paging(int? pageno,bool? fwd,bool? bwd) { if(pageno!=null) { Session["currentpage"] = pageno; } using (HatronEntities DB = new HatronEntities()) { if(fwd!=null && (bool)fwd) { pageno = Convert.ToInt32(Session["currentpage"]) + 1; Session["currentpage"] = pageno; } if (bwd != null && (bool)bwd) { pageno = Convert.ToInt32(Session["currentpage"]) - 1; Session["currentpage"] = pageno; } if (pageno==null) { pageno = 1; } if(pageno<0) { pageno = 1; } int total = DB.EmployeePromotion(0, 0, 0).Count(); int totalPage = (int)Math.Ceiling((double)total / 20); ViewBag.pages = totalPage; if (pageno > totalPage) { pageno = totalPage; } return View (DB.EmployeePromotion(0,0,0).Skip(GetSkip((int)pageno,20)).Take(20).ToList()); } } private static int GetSkip(int pageIndex, int take) { return (pageIndex - 1) * take; } @model IEnumerable @{ Layout = null; }     Paging   
@foreach (var itm in Model) { }
@itm.District @itm.employee @itm.PromotionTo
First page << @for(int itmp =1; itmp< Convert.ToInt32(ViewBag.pages)+1;itmp++) { @itmp.ToString() } >> Last page