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

ASP.NET 靜態新聞頁面生成核心實作:DataReader/DataSet 雙模式與客戶端下載技術

     編輯:關於C語言

專案背景:靜態化帶來的效能紅利

早期 ASP.NET 新聞系統多採動態頁面 (.aspx),每次請求皆觸發資料庫查詢與頁面生命週期,高流量下壓力巨大。本文實作一套批次生成靜態 HTML 的核心模組,採用「排程觸發 → 伺服器端渲染 → 靜態檔案落地」架構,將資料庫讀取與頁面生成集中在離線時段執行,上線環境僅提供靜態檔案,極大降低資料庫負載與回應延遲。

核心架構類別:makeallfiles

namespace makeHtmlfile
{
    public class makeallfiles : System.Web.UI.Page
    {
        public string strcon;           // 連線字串
        public OleDbConnection conn;    // 資料庫連線
        public string strSQL;           // 查詢 SQL

        private void Page_Load(object sender, System.EventArgs e)
        {
            InitialPages(); // 進入點
        }

        public void InitialPages()
        {
            // 從 web.config 讀取 Access 資料庫路徑
            strcon = "provider=Microsoft.jet.OLEDB.4.0;data Source=" 
                     + Server.MapPath(ConfigurationSettings.AppSettings["MDBpath2"]) + ";";
            
            strSQL = "select id, class1id, class2id from news order by id desc";
            
            MakeAreaForShow();                    // 1. 輸出客戶端下載容器
            ReadNewsForWriteFileUserDataReader(); // 2. DataReader 模式生成 (預設)
            // ReadNewsForWriteFileUserDataSet();  // 3. DataSet 模式生成 (備選)
        }
        // ...
    }
}

關鍵技術 1:客戶端非同步下載容器 (IE Download Behavior)

利用 IE 專有 Download 行為 (Behavior) 實現伺服器推送腳本至客戶端執行:

public void MakeAreaForShow()
{
    // 顯示進度/結果的容器
    Response.Write("");
    
    // IE Download Behavior 元件
    Response.Write("");
}
限制: 僅支援 IE 瀏覽器。現代專案建議改用 fetch/SignalR/WebSocket 實現跨瀏覽器即時進度回報。

關鍵技術 2:DataReader 串流式讀取 (低記憶體佔用)

public void ReadNewsForWriteFileUserDataReader()
{
    int num = 0;
    string newsid, class1id, class2id;
    OleDbDataReader dr = null;
    
    using (OleDbConnection conn = new OleDbConnection(strcon))
    {
        conn.Open();
        using (OleDbCommand cmd = new OleDbCommand(strSQL, conn))
        {
            dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                newsid = dr["id"].ToString();
                class1id = dr["class1id"].ToString();
                class2id = dr["class2id"].ToString();
                
                WriteJScript(newsid, class1id, class2id); // 產生客戶端腳本
                num++;
            }
        }
    }
    Response.Write(num.ToString()); // 輸出總筆數
}

優點: 僅保留單筆記錄在記憶體,適合大量資料 (十萬筆以上)。

關鍵技術 3:DataSet 離線快取模式 (適合中小量資料)

public void ReadNewsForWriteFileUserDataSet()
{
    DataSet ds = new DataSet();
    int num = 0;
    
    using (OleDbConnection conn = new OleDbConnection(strcon))
    {
        using (OleDbDataAdapter da = new OleDbDataAdapter(strSQL, conn))
        {
            da.Fill(ds, "news");
        }
    }
    
    num = ds.Tables["news"].Rows.Count;
    foreach (DataRow dr in ds.Tables["news"].Rows)
    {
        string newsid = dr["id"].ToString();
        string class1id = dr["class1id"].ToString();
        string class2id = dr["class2id"].ToString();
        WriteJScript(newsid, class1id, class2id);
    }
    ds = null; // 釋放參考
    Response.Write(num.ToString());
}

優點: 斷線操作、可重複遍歷、支援關聯篩選。缺點: 全量載入記憶體,大資料量易導致 OOM。

關鍵技術 4:動態產生客戶端 JavaScript 觸發下載

public void WriteJScript(string newsid, string class1id, string class2id)
{
    Response.Write("");
}

流程說明:

  1. 伺服器一次輸出數百段 <script> 區塊至瀏覽器。
  2. 瀏覽器依序執行 oDownload.startDownload 向 makefile2.aspx 發送參數化請求。
  3. makefile2.aspx 接收參數 → 查詢完整新聞內容 → 渲染 HTML → 寫入靜態檔案 → 回傳結果字串。
  4. 瀏覽器 onDownloadDone 回呼更新頁面顯示進度。

現代化改造建議

舊架構痛點現代替代方案
IE 專用 Download Behavior前端 fetch + 後端 Web API + Server-Sent Events 或 SignalR 推送進度
Response.Write 字串拼接Razor View / Template Engine (Scriban, Fluid) 渲染 HTML
Access (Jet OLEDB)SQL Server / PostgreSQL / SQLite + Dapper/EF Core
同步阻塞生成Hangfire / Quartz.NET 背景作業 + 進度持久化
實體靜態檔案CDN 快取 + 邊緣渲染 (Next.js ISR, Cloudflare Workers)

完整生成流程圖解

管理員觸發生成
      │
      ▼
makeallfiles.aspx (Page_Load)
      │
      ├─► MakeAreaForShow() → 輸出  + 
      │
      ├─► ReadNewsForWriteFileUserDataReader() 
      │        │
      │        ├─► 迴圈 dr.Read()
      │        │        │
      │        │        └─► WriteJScript(id, class1, class2) → 輸出 
      │        │
      │        └─► 輸出總筆數
      │
      ▼
瀏覽器接收大量 HTML+Script
      │
      ├─► 依序觸發 oDownload.startDownload()
      │        │
      │        ▼
      │   makefile2.aspx?id=xxx&class1id=yyy&class2id=zzz
      │        │
      │        ├─► 查詢新聞完整內容 (標題、內容、時間、作者...)
      │        ├─► 套用 HTML 模板渲染
      │        ├─► File.WriteAllText($"news_{id}.html", htmlContent)
      │        └─► Response.Write("生成成功: news_xxx.html")
      │
      ▼
onDownloadDone() 更新 showImport 顯示進度
      │
      ▼
全數完成 → 靜態化部署完成

安全性與健壯性補強

  • SQL 注入防護: 參數化查詢 (cmd.Parameters.AddWithValue) 替代字串拼接。
  • 路徑遍歷防護: 靜態檔名採用 Guid 或經過 Path.GetInvalidFileNameChars 過濾。
  • 併發控制: 生成鎖 (Mutex/SemaphoreSlim) 避免重複觸發。
  • 錯誤重試: 單篇生成失敗記錄佇列,支援手動/自動重試。
  • 進度持久化: 進度寫入資料庫/Redis,支援瀏覽器重新整理後續傳。

結語

此實作展示了 ASP.NET WebForms 時代「伺服器端推送腳本驅動客戶端批次下載」的經典模式。雖然技術棧已老舊,但串流式讀取 (DataReader)、離線快取 (DataSet)、客戶端非同步協作 的核心思想在現代雲原生架構中依然閃耀。重構時建議採用「背景作業佇列 + 靜態站點生成器 (SSG) + CDN」三位一體方案,徹底解耦生成與服務。

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