ASP.NET MVC'de nasıl sayfalandırabilirim?


85

ASP.NET MVC'de sayfalandırma yapmanın en çok tercih edilen ve en kolay yolu nedir? Yani bir listeyi birkaç göz atılabilir sayfaya bölmenin en kolay yolu budur.

Örnek olarak bir veritabanı / ağ geçidi / depodan aşağıdaki gibi bir eleman listesi aldığımı varsayalım:

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

    return View();
}

Basit olması açısından, eylemim için parametre olarak yalnızca bir sayfa numarası belirtmek istiyorum. Bunun gibi:

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

Yanıtlar:


107

Peki veri kaynağı nedir? Eyleminiz birkaç varsayılan argüman alabilir, yani

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

rota kurulumunda varsayılan olarak ayarlanmıştır, böylece startIndex 0 ve pageSize (diyelim) 20:

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

Beslemeyi bölmek için LINQ'i oldukça kolay bir şekilde kullanabilirsiniz:

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

(veya "startIndex" yerine "pageNumber" kullanıyorsanız bir çarpma yapın)

LINQ-toSQL, EF, vb. İle - bu da veritabanında "oluşturmalı".

Daha sonra, sonraki sayfaya (vb.) Giden eylem bağlantılarını kullanabilmelisiniz:

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

3
Bu ilginç bir yönlendirme örneği, bu yüzden onu yükselteceğim. Henüz LINQ kullanma havasına girmedim, bu yüzden Skip and Take benim için yeni. Ama kesinlikle ihtiyacım olan şey bu. İşte bu yüzden bunu cevap olarak işaretleyeceğim.
Spoike

harika şeyler! Gerçekten çok teşekkür ederim.
Ric Tokyo

MVC2 kullanarak, ActionLinksözdiziminiz sayfayı talep ederken bana bir Derleme Hatası veriyor. CS0103: 'startIndex' adı mevcut bağlamda mevcut değil. Bu teknik MVC2 ile mümkün değil mi?
comecme

@comecme son satırı mı kastediyorsunuz? bu değerleri (veya değişkenleri) sağlamanız gerekir. Ne olduğunu o başlama indeksi / sayfa boyutunda?
Marc Gravell

1
Evet, son satırı kastediyorum. Akımı kullandığını startIndexve pageSizeona eklediğini sanıyordum . Son çağrının değerlerini otomatik olarak kullanacağını ummuştum Search. Nasıl kullanırım startIndexson gelen Searchbenim, ActionLink?
comecme

16

Aynı sorunu yaşadım ve bir Çağrı Cihazı Sınıfı için çok şık bir çözüm buldum

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

Denetleyicinizde arama şöyle görünür:

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

ve size göre:

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

ASP.NET MVC Preview 5 içindir. ASP.NET MVC Beta için çalışacak mı?
Spoike

Bağlantı değişti, kod RC1'e güncellendi (sanırım 1.0 ile de çalışacak, şimdi deneyecek). blogs.taiga.nl/martijn/2008/08/27/paging-with-aspnet-mvc
Palantir

16

Bunu ön uçta yapmanın basit bir yolunu da ele almak istedim:

Denetleyici:

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

Görünüm:

@* 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)Kullanabilmeniz için bir tane gerektirir skip()|| Bunun yanı sıra, bu çok daha fazla oyu hak eden harika bir cevap.
Vahx

4

İşte bu konuda bana yardımcı olan bir bağlantı .

PagedList.MVC NuGet paketini kullanır. Adımları özetlemeye çalışacağım

  1. PagedList.MVC NuGet paketini yükleyin

  2. Proje oluştur

  3. Denetleyiciye ekleusing PagedList;

  4. Sayfayı ayarlamak için eyleminizi değiştirin public ActionResult ListMyItems(int? page) { List list = ItemDB.GetListOfItems(); int pageSize = 3; int pageNumber = (page ?? 1); return View(list.ToPagedList(pageNumber, pageSize)); }

  5. Görünümünüzün altına sayfalama bağlantıları ekleyin @*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
Bunun eski bir soru olduğunu biliyorum, bu yüzden bu yanıtın pek fazla olumlu oyu yok. Ama öyle olmalı, çünkü bu en iyi modern çözüm. PagedList Demo
omgGenerics

2

Kontrolör

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

İş mantığı

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

Toplam sayfa sayısını görüntülemek için görüntüle

 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 uygulamasında sayfalandırma oluşturmanın en kolay yolunun PagedList kitaplığı kullanmak olduğunu düşünüyorum.

Aşağıdaki github deposunda tam bir örnek var. Umarım yardımcı olur.

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

Demo Bağlantısı: http://ajaxpagination.azurewebsites.net/

Kaynak Kodu: https://github.com/ungleng/SimpleAjaxPagedListAndSearchMVC5


1

Varlık

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>

Sayfalama Mantığı

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

Denetleyiciyi Kullanma

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

"Yer" sınıfı nedir?
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>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.