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

ASP.NET 2.0 利用 Ajax + JSON 實現大量頁面資料交互:首次載入、增刪改、序列化完整架構

     編輯:ASP.NET 基礎

頁面初次載入需呈現大量資料(如 6000 筆),且支援前端即時增刪改、最後一次性儲存。傳統 PostBack 會導致大量 ViewState、回應緩慢。本文展示 **ASP.NET AJAX (ScriptManager/PageMethods) + JSON 序列化 + jQuery 前端渲染** 的完整架構。

架構概覽

  • **首次載入**:Server 端 Repeater 綁定渲染初始 HTML
  • **資料序列化**:全部資料 JSON 序列化存入隱藏 TextBox(客戶端快取)
  • **前端操作**:jQuery 操作 DOM(增/刪/改),同步更新 JSON 快取
  • **儲存時**:讀取 JSON 快取,一次性反序列化回 Server 端批次寫入 DB

前端頁面結構

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
    <Scripts>
        <asp:ScriptReference Path="~/Scripts/jquery.js" />
    </Scripts>
</asp:ScriptManager>

<asp:Repeater ID="rptData" runat="server">
    <HeaderTemplate><table class="grid"><thead><tr><th>機構</th><th>群組</th><th>操作</th></tr></thead><tbody></HeaderTemplate>
    <ItemTemplate>
        <tr id='row-<%# Eval("Id") %>'>
            <td><%# Eval("OrgName") %></td>
            <td><%# Eval("GroupName") %></td>
            <td><a href="javascript:deleteRow('<%# Eval("Id") %>')">刪除</a></td>
        </tr>
    </ItemTemplate>
    <FooterTemplate></tbody></table></FooterTemplate>
</asp:Repeater>

<asp:UpdatePanel ID="upPanel" runat="server">
    <ContentTemplate>
        序列化 JSON 快取:<br/>
        <asp:TextBox ID="txtJsonCache" runat="server" TextMode="MultiLine" Rows="10" Width="800px" /><br/>
        新增 ID:<asp:TextBox ID="txtNewId" runat="server" Width="200px" />
        <input type="button" value="新增" onclick="addRow()" />
    </ContentTemplate>
</asp:UpdatePanel>

後端:首次載入與 JSON 序列化

private List _dataSource = new List();

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        InitDataSource();
        BindRepeater();
        SerializeToJsonCache();
    }
}

private void InitDataSource()
{
    for (int i = 0; i < 6000; i++)
    {
        _dataSource.Add(new DataEntity 
        { 
            Id = i.ToString(), 
            OrgName = $"{i}-1", 
            GroupName = $"{i}-2" 
        });
    }
}

private void BindRepeater()
{
    rptData.DataSource = _dataSource;
    rptData.DataBind();
}

private void SerializeToJsonCache()
{
    var jsonObj = new JSONObject();
    for (int i = 0; i < _dataSource.Count; i++)
    {
        var item = _dataSource[i];
        var arr = new JSONArray { item.Id, item.OrgName, item.GroupName };
        jsonObj.Add(i.ToString(), arr);
    }
    txtJsonCache.Text = JSONConvert.SerializeObject(jsonObj); // 自訂 JSON 序列化
}

前端 JavaScript 核心邏輯

<script type="text/javascript">
var jsonCacheId = '<%= txtJsonCache.ClientID %>';
var newIdInputId = '<%= txtNewId.ClientID %>';
var tableBodyId = 'rptData_tbody'; // 需在繼承模板中加入 ID

// 刪除列
function deleteRow(id) {
    // 1. 呼叫 PageMethod 刪除快取項
    $('#' + jsonCacheId).val(id); // 暫存要刪除的 ID
    $('#<%= btnDeleteCache.ClientID %>').click(); // 觸發隱藏按鈕 PageMethod
    
    // 2. 立即移除 DOM
    $('#row-' + id).hide();
}

// 新增列
function addRow() {
    var id = $('#' + newIdInputId).val();
    if (!id) return alert('請輸入 ID');
    
    var json = $('#' + jsonCacheId).val();
    if (json.indexOf(id) > -1) return alert('ID 已存在');
    
    // 呼叫 PageMethod 查詢完整資料
    PageMethods.GetItemById(id, onAddItemSuccess);
}

function onAddItemSuccess(result) {
    if (result == "error") return alert('查無資料');
    
    // 1. 渲染新列
    var html = buildRowHtml(result);
    $('#' + tableBodyId).append(html);
    
    // 2. 更新 JSON 快取
    updateJsonCache(result);
}

function buildRowHtml(jsonStr) {
    var data = eval('(' + jsonStr + ')'); // 解析 JSON 字串
    var tpl = '<tr id="row-{id}"><td>{org}</td><td>{group}</td><td><a href="javascript:deleteRow('{id}')">刪除</a></td></tr>';
    $.each(data, function(i, item) {
        tpl = tpl.replace('{id}', item[0])
                 .replace('{org}', item[1])
                 .replace('{group}', item[2]);
    });
    return tpl;
}

function updateJsonCache(itemJson) {
    var $cache = $('#' + jsonCacheId);
    var old = $cache.val();
    itemJson = itemJson.replace('{', '');
    var newJson = old == '{}' ? old.replace('}', itemJson) : old.replace('}', ',' + itemJson);
    $cache.val(newJson);
}

// 儲存全部變更
function saveAll() {
    var json = $('#' + jsonCacheId).val();
    PageMethods.SaveAllChanges(json, onSaveComplete);
}

function onSaveComplete(result) {
    alert(result ? '儲存成功' : '儲存失敗');
}
</script>

後端 PageMethods(靜態 WebMethod)

[WebMethod]
public static string GetItemById(string id)
{
    // 模擬查詢 DB
    var item = DataRepository.GetById(id);
    if (item == null) return "error";
    return $"{{\"Id\":\"{item.Id}\",\"OrgName\":\"{item.OrgName}\",\"GroupName\":\"{item.GroupName}\"}}";
}

[WebMethod]
public static bool SaveAllChanges(string json)
{
    try
    {
        var data = JSONConvert.DeserializeObject(json); // 自訂反序列化
        foreach (var kvp in data)
        {
            var arr = (JSONArray)kvp.Value;
            var entity = new DataEntity
            {
                Id = arr[0].ToString(),
                OrgName = arr[1].ToString(),
                GroupName = arr[2].ToString()
            };
            DataRepository.Upsert(entity);
        }
        return true;
    }
    catch { return false; }
}

自訂 JSON 序列化類別(無第三方依賴)

public static class JSONConvert
{
    public static string SerializeObject(JSONObject obj) { /* ... */ }
    public static JSONObject DeserializeObject(string json) { /* ... */ }
    // 內部用正則解析、轉義 ; , { } [ ] " 等特殊字元
}

public class JSONObject : Dictionary { /* 字串值自動轉義 */ }
public class JSONArray : List { /* 字串值自動轉義 */ }

關鍵設計決策

現代化遷移建議

  • **前端**:Vue/React + Web API,狀態管理取代隱藏 TextBox
  • **序列化**:`System.Text.Json` / `Newtonsoft.Json` 內建高效能
  • **通訊**:`fetch` / `axios` 取代 `PageMethods`
  • **後端**:ASP.NET Core Minimal API / Controller

此架構在 .NET 2.0/3.5 時代是「無 ViewState、高互動、大資料」的經典解法,核心思想——**首屏 Server 渲染 + 客戶端狀態管理 + 批次同步**——至今仍具參考價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
決策點方案理由
首次渲染Server 端 RepeaterSEO 友善、首屏速度快、無閃爍
客戶端快取隱藏 TextBox 存 JSONUpdatePanel 部分更新自動同步、無需 Session
前端增刪改jQuery DOM 操作 + JSON 同步零 PostBack、體驗流暢
序列化自訂 JSONObject/JSONArray.NET 2.0 無內建 JSON、避免引入第三方 DLL
批次儲存PageMethod 接收完整 JSON單次請求、交易性處理、減少網路往返