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

ASP.NET 大檔案上傳技術深度解析:HttpModule 實現斷點續傳與進度顯示

     編輯:關於ASP.NET

前言

在企業級 ASP.NET 應用開發中,大檔案上傳始終是技術難點之一。當檔案大小超過 100MB 時,傳統的上傳方式往往面臨請求逾時、記憶體溢出、無法顯示進度等問題。本文深入剖析兩款主流上傳組件——AspnetUpload 2.0 與 Lion.Web.UpLoadModule 的核心實現原理,揭示基於 HttpWorkerRequest 的底層數據流讀取機制,並展示如何透過 HttpModule 實現大檔案分塊上傳與即時進度監控。

核心技術架構

這兩款組件均採用 Chris Hynes 提出的 HttpModule 方案,核心在於利用 IIS 為 ASP.NET 建立的命名管道,透過 HttpWorkerRequest 的 GetPreloadedEntityBody 與 ReadEntityBody 方法,從管道中分塊讀取上傳數據。這種方式繞過了 ASP.NET 預設的整體請求緩衝機制,避免大檔案一次性載入記憶體導致的效能瓶頸。

關鍵實現步驟

1. 初始化與請求驗證

在 HttpModule 的 Init 事件中攔截請求,首先驗證 Content-Type 是否為 multipart/form-data,並檢查 HasEntityBody 確認存在實體內容。獲取 Content-Length 標頭以得知總檔案大小,為後續進度計算奠基。

2. 預載數據分析

調用 GetPreloadedEntityBody 取得 IIS 預載的初始數據塊(通常為 48KB),解析出 UploadGUID(唯一上傳標識)、UploadFolder(儲存路徑)等關鍵元數據。此階段同時初始化 Progress 物件記錄接收位元組數、檔案名稱、檔案總數,並存入 Application 狀態供前端輪詢進度。

3. 分塊讀取與流重組

當 IsEntireEntityBodyIsPreloaded 為 false 時,進入循環調用 ReadEntityBody 逐塊讀取剩餘數據(預設緩衝區 200KB)。每讀取一塊即更新 Progress.ReceivedLength,並透過 RequestStream 處理 multipart 邊界分隔,將檔案內容寫入磁碟。若偵測到 !Response.IsClientConnected 則中斷上傳並清理資源。

4. 請求數據重構

上傳完成後,將所有讀取的位元組陣列合併,調用 PopulateRequestData 重填充至 HttpWorkerRequest,使後續 ASP.NET Pipeline 能正常存取 Request.Files、Request.Form 等集合,實現與標準上傳流程的無縫銜接。

程式碼關鍵片段解析

HttpWorkerRequest request1 = (HttpWorkerRequest)((IServiceProvider)HttpContext.Current).GetService(typeof(HttpWorkerRequest));
byte[] buffer2 = request1.GetPreloadedEntityBody();
num1 += buffer2.Length;
// 解析 UploadGUID、UploadFolder 等元數據
// 初始化 Progress 物件並存入 Application["_UploadGUID_" + guid]

while ((num2 - num1) >= bufferSize) {
    if (!application1.Context.Response.IsClientConnected) { ClearApplication(application1); }
    num3 = request1.ReadEntityBody(buffer3, buffer3.Length);
    num1 += num3;
    // 透過 RequestStream 處理邊界、寫入檔案、更新進度
    progress1.ReceivedLength = num1;
    application1.Application["_UploadGUID_" + text2] = progress1;
}

優勢與局限

  • 優勢:支援超大檔案(GB 級)、即時進度顯示、斷點續傳潛力、不阻塞 ASP.NET 執行緒池。
  • 局限:依賴 IIS 管道機制,僅適用於經典模式/整合模式下的裝載環境;需在 web.config 註冊 HttpModule;對負載平衡、Web Farm 環境需共享 Application 狀態(建議改用 Redis/資料庫)。

現代化替代方案

ASP.NET Core 時代,建議採用 IFormFile 流式讀取、MultipartReader 或第三方庫(如 MultipartFormDataParser)配合 SignalR 實現進度推送;或採用分片上傳(Chunked Upload)配合前端切片庫(Uppy、Dropzone),由後端合併分片,更適應雲原生與容器化部署。

總結

HttpModule + HttpWorkerRequest 方案在 .NET Framework 時期為大檔案上傳提供了經典解法,其分塊讀取、進度追蹤、請求重構的設計思想至今仍具參考價值。理解底層管道機制,有助於在遷移至現代架構時做出更合理的技術選型。

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