分頁是 Web 應用的基礎功能。本文分享一個同時相容 WebForms 與 ASP.NET MVC 的分頁元件 Pager,採用介面導向設計,支援動態查詢參數傳遞,靈活易擴充。
IPagedList,封裝 Skip/Take 邏輯,支援 IEnumerable<T> 與 IQueryable<T> (透過擴充方法)。IQueryable.ToPagedList() 擴充方法,一鍵完成資料庫分頁查詢。public interface IPagedList
{
int PageIndex { get; set; }
int PageSize { get; set; }
int TotalItemCount { get; set; }
int TotalPageCount { get; }
}
public class PagedList<T> : List<T>, IPagedList
{
public int PageIndex { get; set; }
public int PageSize { get; set; }
public int TotalItemCount { get; set; }
public int TotalPageCount
=> TotalItemCount % PageSize == 0
? TotalItemCount / PageSize
: TotalItemCount / PageSize + 1;
public PagedList(IEnumerable<T> source, int pageIndex, int pageSize)
{
PageIndex = pageIndex;
PageSize = pageSize;
TotalItemCount = source?.Count() ?? 0;
if (source?.Any() == true)
AddRange(source.Skip(PageSize * (PageIndex - 1)).Take(PageSize));
}
}
public static class PagerLinqExtension
{
public static PagedList<T> ToPagedList<T>(
this IQueryable<T> source, int pageIndex, int pageSize)
{
return new PagedList<T>(source, pageIndex, pageSize);
}
}
使用時:var paged = db.Products.Where(p => p.Active).ToPagedList(page, 20); 會自動產生 SKIP/TAKE SQL。
public static class PagerHelper
{
// 基本版:僅需 URL 與分頁資料
public static string Pager(string url, IPagedList pagedList) { ... }
// 進階版:支援 dynamic 物件攜帶額外查詢參數 (如 new { cid = 5, keyword = "abc" })
public static string Pager(string url, IPagedList pagedList, dynamic objAttr)
{
// 透過反射讀取 objAttr 屬性組成 querystring
// 產生連結如:/Products?cid=5&keyword=abc&pageIndex=2
}
}
<%= PagerHelper.Pager("Products.aspx", pageList, new { cid = CurrentCategoryId }) %>
先建立 HtmlHelper 擴充:
namespace System.Web.Mvc.Html
{
public static class HtmlExtension
{
public static IHtmlString Pager(this HtmlHelper helper,
string url, IPagedList pagedList, dynamic objAttr = null)
{
return helper.Raw(PagerHelper.Pager(url, pagedList, objAttr));
}
}
}
View 中:
@Html.Pager("Products", Model, new { cid = ViewBag.Cid, keyword = ViewBag.Keyword })
dynamic + 反射,自動將匿名物件屬性轉為 QueryString,避免手動拼接 URL。System.Web、System.Linq,無第三方套件。這套 Pager 元件展示了「介面抽離、擴充方法、動態參數綁定」等實用模式,可直接納入專案或作為客製化分頁的起點。