首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET jQuery Ajax + JSON 無刷新分頁完整實作 (WebForms + ASHX/PageMethod)

     編輯:ASP.NET 基礎

架構圖

[前端 jQuery] --Ajax POST {pageIndex, pageSize}→ [後端 SupplyAJAX.aspx/ASHX] → [SQL 分頁查詢] → [JSON 序列化] → [前端渲染 Table + 分頁控件]

1. 前端頁面

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AjaxPaging.aspx.cs" Inherits="Demo.AjaxPaging" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Ajax 無刷新分頁</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/simple-pagination@1.0.1/jquery.simplePagination.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/simple-pagination@1.0.1/simplePagination.css" rel="stylesheet" />
    <style>
        .table-responsive { margin-top: 20px; }
        #pagination { margin: 20px 0; text-align: center; }
    </style>
</head>
<body>
    <div class="container">
        <h3>學生名單 (Ajax 分頁)</h3>
        <div class="table-responsive">
            <table class="table table-striped table-hover" id="tblStudents">
                <thead class="table-dark">
                    <tr><th>ID</th><th>姓名</th><th>性別</th></tr>
                </thead>
                <tbody></tbody>
            </table>
        </div>
        <div id="pagination"></div>
    </div>

    <script>
        const PAGE_SIZE = 10;
        let totalRecords = 0;

        $(function () {
            loadPage(1); // 首次載入第 1 頁
        });

        function loadPage(pageIndex) {
            $.ajax({
                url: 'SupplyAJAX.ashx', // 或 .aspx
                type: 'POST',
                dataType: 'json',
                data: { 
                    action: 'list', 
                    pageIndex: pageIndex, 
                    pageSize: PAGE_SIZE,
                    _: Date.now() // 防快取
                },
                beforeSend: () => $('#tblStudents tbody').html('載入中...'),
                success: function (resp) {
                    if (resp.success) {
                        renderTable(resp.data);
                        totalRecords = resp.total;
                        initPagination(pageIndex);
                    } else {
                        showError(resp.message);
                    }
                },
                error: function (xhr, status, err) {
                    showError('請求失敗:' + err);
                }
            });
        }

        function renderTable(list) {
            var html = '';
            $.each(list, function (i, item) {
                html += `${item.Id}${item.Name}${item.Gender}`;
            });
            $('#tblStudents tbody').html(html);
        }

        function initPagination(currentPage) {
            $('#pagination').pagination({
                items: totalRecords,
                itemsOnPage: PAGE_SIZE,
                currentPage: currentPage,
                displayedPages: 3,
                edges: 1,
                prevText: '上一頁',
                nextText: '下一頁',
                onPageClick: function (page, evt) {
                    evt.preventDefault();
                    loadPage(page);
                }
            });
        }

        function showError(msg) {
            $('#tblStudents tbody').html(`${msg}`);
            $('#pagination').empty();
        }
    </script>
</body>
</html>

2. 後端處理常式

<%@ WebHandler Language="C#" Class="SupplyAJAX" %>
using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Web.Script.Serialization;
using System.Text;

public class SupplyAJAX : IHttpHandler
{
    private static readonly JavaScriptSerializer Json = new JavaScriptSerializer();
    private static readonly List _allStudents = GenerateMockData(1000); // 模擬 1000 筆

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "application/json; charset=utf-8";
        string action = context.Request["action"];

        try
        {
            switch (action)
            {
                case "list":
                    HandleList(context);
                    break;
                case "count":
                    context.Response.Write(Json.Serialize(new { success = true, total = _allStudents.Count }));
                    break;
                default:
                    WriteError("未知 action");
                    break;
            }
        }
        catch (Exception ex)
        {
            WriteError("伺服器錯誤:" + ex.Message);
        }
    }

    private void HandleList(HttpContext context)
    {
        int pageIndex = int.Parse(context.Request["pageIndex"] ?? "1");
        int pageSize = int.Parse(context.Request["pageSize"] ?? "10");

        if (pageIndex < 1) pageIndex = 1;

        // 記憶體分頁 (實務換成 SQL: OFFSET/FETCH 或 ROW_NUMBER)
        var paged = _allStudents
            .Skip((pageIndex - 1) * pageSize)
            .Take(pageSize)
            .ToList();

        var result = new
        {
            success = true,
            total = _allStudents.Count,
            data = paged
        };
        context.Response.Write(Json.Serialize(result));
    }

    private void WriteError(string msg)
    {
        context.Response.Write(Json.Serialize(new { success = false, message = msg }));
    }

    public bool IsReusable => false;

    // 模擬資料
    private static List GenerateMockData(int count)
    {
        var list = new List(count);
        for (int i = 1; i <= count; i++)
            list.Add(new Student { Id = i, Name = $"學生{i:D4}", Gender = i % 2 == 0 ? "女" : "男" });
        return list;
    }
}

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Gender { get; set; }
}

3. 關鍵技術點解析

環節重點
分頁參數前端傳 `pageIndex` (1-based) + `pageSize`,後端 `Skip/Take` 或 SQL `OFFSET/FETCH`
總筆數首次載入或每次回傳 `total`,分頁控件需知總數計算頁碼
JSON 格式`{ success: true, total: 1000, data: [...] }` 統一封裝,前端統一錯誤處理
防快取查詢字串加 `_=Date.now()` 或 `cache: false`
序列化`JavaScriptSerializer` (內建) 或 `Newtonsoft.Json` (效能更好、支援 DateTime 格式化)
分頁控件`simplePagination` / `twbsPagination` / `laypage` / 自寫,核心是 `onPageClick` 觸發 `loadPage`
載入狀態`beforeSend` 顯示「載入中...」,避免使用者重複點擊

4. 進階:SQL Server 高效分頁

-- SQL Server 2012+ 標準語法
SELECT Id, Name, Gender
FROM Students
ORDER BY Id
OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY;

-- 取得總數 (可用 COUNT(*) OVER() 窗口函數單查詢完成,或分兩次查)
SELECT COUNT(*) FROM Students;

配合 Dapper / EF Core:

var sql = @"SELECT * FROM Students ORDER BY Id OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY;
            SELECT COUNT(*) FROM Students;";
using (var multi = conn.QueryMultiple(sql, new { Offset = (pageIndex-1)*pageSize, PageSize = pageSize }))
{
    var data = multi.Read().ToList();
    var total = multi.ReadSingle();
    return new { success = true, total, data };
}

5. 現代化替代:ASP.NET Core + fetch + TagHelper


// Controller
[HttpPost]
public IActionResult List(int pageIndex = 1, int pageSize = 10)
{
    var (data, total) = _service.GetPaged(pageIndex, pageSize);
    return Json(new { success = true, total, data });
}

// 前端 (Razor 頁面)
...

總結

jQuery Ajax + JSON 無刷新分頁是 WebForms 時代提升體驗的經典模式。核心在於:統一 JSON 封裝、前端分頁控件與後端分頁邏輯對齊、防快取、載入狀態、錯誤統一處理。現代專案請直接使用 ASP.NET Core Web API + fetch/axios + 前端框架 (Vue/React/Blazor),獲得型別安全、組件化、測試友善的開發體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved