How do I do pagination in ASP.NET MVC?
Well, what is the data source? Your action could take a few defaulted arguments, i.e.
ActionResult Search(string query, int startIndex, int pageSize) {...}
defaulted in the routes setup so that startIndex is 0 and pageSize is (say) 20:
routes.MapRoute("Search", "Search/{query}/{startIndex}",
new
{
controller = "Home", action = "Search",
startIndex = 0, pageSize = 20
});
To split the feed, you can use LINQ quite easily:
var page = source.Skip(startIndex).Take(pageSize);
(or do a multiplication if you use "pageNumber" rather than "startIndex")
With LINQ-toSQL, EF, etc - this should "compose" down to the database, too.
You should then be able to use action-links to the next page (etc):
<%=Html.ActionLink("next page", "Search", new {
query, startIndex = startIndex + pageSize, pageSize }) %>
I wanted to cover a simple way of doing this with the front end too:
Controller:
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);
}
View:
@* rest of file with view *@
@if (ViewBag.Page > 0)
{
<a href="@Url.Action("Index", new { page = ViewBag.Page - 1 })"
class="btn btn-default">
« Prev
</a>
}
@if (ViewBag.Page < ViewBag.MaxPage)
{
<a href="@Url.Action("Index", new { page = ViewBag.Page + 1 })"
class="btn btn-default">
Next »
</a>
}
I had the same problem and found a very elegant solution for a Pager Class from
http://blogs.taiga.nl/martijn/2008/08/27/paging-with-aspnet-mvc/
In your controller the call looks like:
return View(partnerList.ToPagedList(currentPageIndex, pageSize));
and in your view:
<div class="pager">
Seite: <%= Html.Pager(ViewData.Model.PageSize,
ViewData.Model.PageNumber,
ViewData.Model.TotalItemCount)%>
</div>
Here's a link that helped me with this.
It uses PagedList.MVC NuGet package. I'll try to summarize the steps
Install the PagedList.MVC NuGet package
Build project
Add
using PagedList;
to the controllerModify your action to set page
public ActionResult ListMyItems(int? page) { List list = ItemDB.GetListOfItems(); int pageSize = 3; int pageNumber = (page ?? 1); return View(list.ToPagedList(pageNumber, pageSize)); }
Add paging links to the bottom of your view
@*Your existing view*@ Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount @Html.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
Controller
[HttpGet]
public async Task<ActionResult> 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);
}
BusinessLogic
public List<Match> GetMatchCore(int page, int pageSize, out int totalRecord, out int totalPage)
{
SignalRDataContext db = new SignalRDataContext();
var query = new List<Match>();
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;
}
View for displaying total page count
if (ViewBag.dbCount != null)
{
for (int i = 1; i <= ViewBag.dbCount; i++)
{
<ul class="pagination">
<li>@Html.ActionLink(@i.ToString(), "Index", "Grid", new { page = @i },null)</li>
</ul>
}
}