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

ASP.NET FileUpload 大檔上傳設定與錯誤攔截完整指南 (web.config 優化)

     編輯:ASP.NET 基礎

核心設定:httpRuntime 關鍵屬性

在 web.config 的 <system.web> 節點下設定 <httpRuntime>,控制上傳大小限制與請求逾時:

<system.web>
    <httpRuntime 
        maxRequestLength="102400"         <!-- 最大上傳 100 MB (單位 KB) -->
        executionTimeout="600"            <!-- 請求逾時 600 秒 (10 分鐘) -->
        requestLengthDiskThreshold="256"  <!-- 超過 256 KB 寫入磁碟暫存 -->
        useFullyQualifiedRedirectUrl="false"
        minFreeThreads="8"
        minLocalRequestFreeThreads="4"
        appRequestQueueLimit="100"
        enableVersionHeader="false"       <!-- 安全性:隱藏版本資訊 -->
    />
</system.web>

屬性詳細說明

屬性單位預設值說明
maxRequestLengthKB4096 (4 MB)超過此大小直接回傳 HTTP 400,不進入 ASP.NET 管線
executionTimeout秒110請求執行最大秒數,大檔上傳需調大
requestLengthDiskThresholdKB256超過此大小改用磁碟暫存,減輕記憶體壓力 (ASP.NET 2.0+)

IIS 7+ 整合模式額外設定:requestFiltering

IIS 7 以上預設限制請求內容長度為 30 MB (maxAllowedContentLength,單位**位元組**),需同步調整:

<system.webServer>
    <security>
        <requestFiltering>
            <requestLimits maxAllowedContentLength="104857600" /> <!-- 100 MB = 100*1024*1024 位元組 -->
        </requestLimits>
    </requestFiltering>
    </security>
</system.webServer>

大檔上傳錯誤攔截:無法用 try-catch 捕獲的 400 錯誤

當上傳檔案超過 maxRequestLength,ASP.NET 在管線早期直接拋回 HTTP 400,**不會進入** Page_Load、Button_Click 或 Application_Error。前端瀏覽器顯示「網頁無法顯示」或 IIS 預設錯誤頁。

解決方案:自訂錯誤頁面 + 前端參數判斷

1. web.config 開啟自訂錯誤

<system.web>
    <customErrors mode="On" defaultRedirect="Error.aspx">
        <error statusCode="400" redirect="UploadError.aspx" />
        <error statusCode="404" redirect="NotFound.aspx" />
    </customErrors>
</system.web>

2. 專用上傳錯誤頁面 (UploadError.aspx)

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UploadError.aspx.cs" Inherits="Demo.UploadError" %>
<!DOCTYPE html>
<html>
<head><title>上傳錯誤</title></head>
<body>
    <form id="form1" runat="server">
        <div style="padding:20px; color:red; font-size:1.2em;">
            <asp:Label ID="lblMsg" runat="server" />
        </div>
        <asp:Button ID="btnBack" runat="server" Text="返回上傳頁" OnClick="btnBack_Click" />
    </form>
</body>
</html>
using System;
using System.Web.UI;

namespace Demo
{
    public partial class UploadError : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 判斷是否為 maxRequestLength 超限錯誤
            // 此時 Server.GetLastError() 為 null,需從 QueryString 或 Referrer 判斷
            string referrer = Request.UrlReferrer?.ToString() ?? "";
            
            if (referrer.Contains("UploadFile.aspx")) // 假設上傳頁面
            {
                lblMsg.Text = "❌ 上傳失敗:檔案大小超過系統限制 (最大 100 MB)。請縮減檔案後重試。";
            }
            else
            {
                lblMsg.Text = "發生未預期的錯誤 (HTTP 400)。";
            }
        }

        protected void btnBack_Click(object sender, EventArgs e)
        {
            Response.Redirect("UploadFile.aspx?err=filesize");
        }
    }
}

3. 上傳頁面顯示友善錯誤訊息

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack && Request.QueryString["err"] == "filesize")
    {
        // 使用 ClientScript 註冊啟動腳本,避免重複彈窗
        ClientScript.RegisterStartupScript(GetType(), "sizeAlert", 
            "alert('檔案過大,請確認檔案小於 100 MB');", true);
    }
}

更優雅的方案:AJAX 非同步上傳 + 進度條 (避免大檔封鎖 UI)

傳統 FileUpload 為同步 Postback,大檔上傳時瀏覽器無回應、無進度。建議改用:

  • HTML5 File API + XMLHttpRequest Level 2:原生支援進度事件 (xhr.upload.onprogress)、分塊上傳、暫停/續傳
  • 成熟前端元件:Fine Uploader、Dropzone.js、Uppy、FilePond
  • 後端接收:ASP.NET Web API / Generic Handler (.ashx) / ASP.NET Core Controller,配合 MultipartFormDataStreamProvider 流式處理,不佔用大量記憶體

前端 HTML5 進度上傳核心程式碼

<input type="file" id="fileInput" multiple />
<button onclick="uploadFiles()">開始上傳</button>
<progress id="progressBar" value="0" max="100"></progress>
<div id="status"></div>

<script>
async function uploadFiles() {
    const files = document.getElementById('fileInput').files;
    if (!files.length) return alert('請選擇檔案');

    for (const file of files) {
        const formData = new FormData();
        formData.append('file', file);

        try {
            const response = await fetch('/api/upload', {
                method: 'POST',
                body: formData
                // 進度需用 XMLHttpRequest,fetch 目前無原生進度支援
            });
            const result = await response.json();
            document.getElementById('status').innerHTML += `✅ ${file.name}: ${result.message}<br>`;
        } catch (err) {
            document.getElementById('status').innerHTML += `❌ ${file.name}: ${err}<br>`;
        }
    }
}

// XMLHttpRequest 版本 (支援進度)
function uploadWithProgress(file) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', '/api/upload');
        xhr.upload.onprogress = (e) => {
            if (e.lengthComputable) {
                const percent = Math.round((e.loaded / e.total) * 100);
                document.getElementById('progressBar').value = percent;
            }
        };
        xhr.onload = () => xhr.status === 200 ? resolve(xhr.response) : reject(xhr.statusText);
        xhr.onerror = () => reject('網路錯誤');
        xhr.send(new FormData().append('file', file));
    });
}
</script>

伺服器端資源評估:記憶體與磁碟

伺服器記憶體建議單檔上限建議同時上傳數備註
2 GB50 MB3-5小型專案
4 GB100 MB5-8中型專案
8 GB+200-500 MB10+需搭配分塊上傳

超過建議值易導致 OutOfMemoryException 或請求佇列堵塞。企業級系統必須實作分塊上傳 (Chunked Upload):前端將大檔切割 1-5 MB 片段,後端暫存合併,單次請求體積可控。

安全性檢查清單 (上傳功能上線必驗)

  1. ✅ 檔案副檔名白名單驗證 (雙重:前端 + 後端)
  2. ✅ MIME Type 驗證 (PostedFile.ContentType)
  3. ✅ 檔案簽名 檢查 (讀取 Header Bytes 判斷真實格式)
  4. ✅ 檔案大小限制 (web.config + IIS + 前端 JS 雙重)
  5. ✅ 儲存路徑非 Web 可執行目錄 (防止上傳 .aspx/.ashx/.php 執行)
  6. ✅ 檔案重新命名 (GUID + 原始副檔名,防覆蓋、防路徑遍歷)
  7. ✅ 病毒掃描整合 (ClamAV / Windows Defender / 雲端 API)
  8. ✅ 存取權限控管 (Authentication + Authorization)

總結

ASP.NET FileUpload 大檔上傳核心在於 web.config 雙重設定 (httpRuntime.maxRequestLength + requestFiltering.maxAllowedContentLength) 與 executionTimeout 調整。超過限制的 400 錯誤無法用 try-catch 捕獲,必須透過 customErrors 導向專用錯誤頁面友善提示。現代專案強烈建議採用 HTML5 非同步分塊上傳架構,徹底解決記憶體、逾時、使用者體驗三大痛點。

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