ASP.NET MVC에서 페이지 매김을 어떻게 수행합니까?


85

ASP.NET MVC에서 페이지 매김을 수행하는 가장 선호되고 쉬운 방법은 무엇입니까? 즉, 목록을 여러 개의 검색 가능한 페이지로 나누는 가장 쉬운 방법은 무엇입니까?

예를 들어 다음과 같이 데이터베이스 / 게이트웨이 / 저장소에서 요소 목록을 가져 온다고 가정 해 보겠습니다.

public ActionResult ListMyItems()
{
    List<Item> list = ItemDB.GetListOfItems();
    ViewData["ItemList"] = list;

    return View();
}

간단히하기 위해 내 작업에 대한 페이지 번호 만 매개 변수로 지정하고 싶습니다. 이렇게 :

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

답변:


106

글쎄, 데이터 소스는 무엇입니까? 귀하의 작업은 몇 가지 기본 인수를 취할 수 있습니다.

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

startIndex가 0이고 pageSize가 20이되도록 경로 설정에 기본값이 지정됩니다.

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

피드를 분할하려면 LINQ를 매우 쉽게 사용할 수 있습니다.

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

(또는 "startIndex"가 아닌 "pageNumber"를 사용하는 경우 곱셈을 수행하십시오.)

LINQ-toSQL, EF 등을 사용하면 데이터베이스에도 "구성"되어야합니다.

그런 다음 다음 페이지 (등)에 대한 작업 링크를 사용할 수 있어야합니다.

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

3
이것은 흥미로운 라우팅 예이므로 찬성하겠습니다. 아직 LINQ를 사용하지 않았으므로 Skip and Take가 처음입니다. 그러나 그것이 내가 필요한 것입니다. 이것이 제가 답으로 표시하는 이유입니다.
Spoike

굉장한 물건! 참으로 대단히 감사합니다.
Ric Tokyo

MVC2를 사용하면 ActionLink구문에서 페이지를 요청할 때 컴파일 오류가 발생합니다. CS0103 : 현재 컨텍스트에 'startIndex'라는 이름이 없습니다. 이 기술은 MVC2에서 가능하지 않습니까?
comecme

@comecme 마지막 줄을 의미합니까? 이러한 값 (또는 변수)을 제공해야합니다. 무엇 이며 그 시작 인덱스 / 페이지 크기는?
Marc Gravell

1
네, 마지막 줄을 의미합니다. 나는 당신이 현재를 사용하고 있다고 생각 하고 그것에 startIndex추가 pageSize합니다. 에 대한 마지막 호출의 값을 자동으로 사용하기를 바랍니다 Search. 내 startIndex마지막 Search에서 어떻게 사용 ActionLink합니까?
comecme

16

나는 같은 문제가 있었고 호출기 클래스에 대한 매우 우아한 해결책을 찾았습니다.

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

컨트롤러에서 호출은 다음과 같습니다.

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

그리고 당신의 관점에서 :

<div class="pager">
    Seite: <%= Html.Pager(ViewData.Model.PageSize, 
                          ViewData.Model.PageNumber,
                          ViewData.Model.TotalItemCount)%>
</div>

ASP.NET MVC Preview 5 용입니다. ASP.NET MVC Beta에서도 작동합니까?
Spoike

링크가 변경되고 코드가 RC1로 업데이트되었습니다 (1.0에서도 작동 할 것으로 예상되며 지금 사용해 볼 것입니다). blogs.taiga.nl/martijn/2008/08/27/paging-with-aspnet-mvc
Palantir

16

프런트 엔드에서도이 작업을 수행하는 간단한 방법을 다루고 싶었습니다.

제어 장치:

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);
}

전망:

@* rest of file with view *@

@if (ViewBag.Page > 0)
{
    <a href="@Url.Action("Index", new { page = ViewBag.Page - 1 })" 
       class="btn btn-default">
        &laquo; Prev
    </a>
}
@if (ViewBag.Page < ViewBag.MaxPage)
{
    <a href="@Url.Action("Index", new { page = ViewBag.Page + 1 })" 
       class="btn btn-default">
        Next &raquo;
    </a>
}

3
var data = this.dataSource.Skip(page * PageSize).Take(PageSize).ToList();orderBy(o => o.Id)사용하려면 먼저 a가 필요합니다 skip()|| 그 외에도 이것은 더 많은 찬성 투표를받을 가치가있는 훌륭한 답변입니다.
Vahx

4

여기에 도움 이 된 링크 가 있습니다.

PagedList.MVC NuGet 패키지를 사용합니다. 단계를 요약 해 보겠습니다

  1. PagedList.MVC NuGet 패키지 설치

  2. 프로젝트 빌드

  3. 컨트롤러에 추가using PagedList;

  4. 페이지 설정에 대한 작업 수정 public ActionResult ListMyItems(int? page) { List list = ItemDB.GetListOfItems(); int pageSize = 3; int pageNumber = (page ?? 1); return View(list.ToPagedList(pageNumber, pageSize)); }

  5. 보기 하단에 페이징 링크 추가 @*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 }))


1
나는 이것이 오래된 질문이라는 것을 알고 있습니다. 그래서이 답변에 많은 찬성 투표가 없습니다. 그러나 이것이 가장 현대적인 솔루션이기 때문에 그렇게해야합니다. PagedList 데모
omgGenerics

2

제어 장치

 [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;
    }

총 페이지 수를 표시하기위한보기

 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>
        }
    }

2

ASP.NET MVC 응용 프로그램에서 페이지 매김을 만드는 가장 쉬운 방법은 PagedList 라이브러리를 사용하는 것입니다.

다음 github 저장소에 완전한 예제가 있습니다. 도움이 되길 바랍니다.

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();
    }
}

데모 링크 : http://ajaxpagination.azurewebsites.net/

소스 코드 : https://github.com/ungleng/SimpleAjaxPagedListAndSearchMVC5


1

실재

public class PageEntity
{
    public int Page { get; set; }
    public string Class { get; set; }
}

public class Pagination
{
    public List<PageEntity> 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

<nav>
    <div class="navigation" style="text-align: center">
        <ul class="pagination">
            <li class="page-item @Model.NextClass"><a class="page-link" href="?page=@(@Model.Previous+@Model.Query)">&laquo;</a></li>
            @foreach (var item in @Model.Pages)
            {
                <li class="page-item @item.Class"><a class="page-link" href="?page=@(item.Page+@Model.Query)">@item.Page</a></li>
            }
            <li class="page-item @Model.NextClass"><a class="page-link" href="?page=@(@Model.Next+@Model.Query)">&raquo;</a></li>
        </ul>
    </div>
 </nav>

페이징 로직

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<PageEntity>();
    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;
}

컨트롤러 사용

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);
}

"Place"클래스는 무엇입니까?
FreeVice

1
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<EmployeePromotion_Result>
@{
  Layout = null;
}

 <!DOCTYPE html>

 <html>
 <head>
    <meta name="viewport" content="width=device-width" />
    <title>Paging</title>
  </head>
  <body>
 <div> 
    <table border="1">
        @foreach (var itm in Model)
        {
 <tr>
   <td>@itm.District</td>
   <td>@itm.employee</td>
   <td>@itm.PromotionTo</td>
 </tr>
        }
    </table>
    <a href="@Url.Action("Paging", "Home",new { pageno=1 })">First  page</a> 
    <a href="@Url.Action("Paging", "Home", new { bwd =true })"><<</a> 
    @for(int itmp =1; itmp< Convert.ToInt32(ViewBag.pages)+1;itmp++)
   {
       <a href="@Url.Action("Paging", "Home",new { pageno=itmp   })">@itmp.ToString()</a>
   }
    <a href="@Url.Action("Paging", "Home", new { fwd = true })">>></a> 
    <a href="@Url.Action("Paging", "Home", new { pageno =                                                                               Convert.ToInt32(ViewBag.pages) })">Last page</a> 
</div>
   </body>
  </html>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.