在 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>
| 屬性 | 單位 | 預設值 | 說明 |
|---|---|---|---|
maxRequestLength | KB | 4096 (4 MB) | 超過此大小直接回傳 HTTP 400,不進入 ASP.NET 管線 |
executionTimeout | 秒 | 110 | 請求執行最大秒數,大檔上傳需調大 |
requestLengthDiskThreshold | KB | 256 | 超過此大小改用磁碟暫存,減輕記憶體壓力 (ASP.NET 2.0+) |
IIS 7 以上預設限制請求內容長度為 30 MB (maxAllowedContentLength,單位**位元組**),需同步調整:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="104857600" /> <!-- 100 MB = 100*1024*1024 位元組 -->
</requestLimits>
</requestFiltering>
</security>
</system.webServer>
當上傳檔案超過 maxRequestLength,ASP.NET 在管線早期直接拋回 HTTP 400,**不會進入** Page_Load、Button_Click 或 Application_Error。前端瀏覽器顯示「網頁無法顯示」或 IIS 預設錯誤頁。
<system.web>
<customErrors mode="On" defaultRedirect="Error.aspx">
<error statusCode="400" redirect="UploadError.aspx" />
<error statusCode="404" redirect="NotFound.aspx" />
</customErrors>
</system.web>
<%@ 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");
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack && Request.QueryString["err"] == "filesize")
{
// 使用 ClientScript 註冊啟動腳本,避免重複彈窗
ClientScript.RegisterStartupScript(GetType(), "sizeAlert",
"alert('檔案過大,請確認檔案小於 100 MB');", true);
}
}
傳統 FileUpload 為同步 Postback,大檔上傳時瀏覽器無回應、無進度。建議改用:
xhr.upload.onprogress)、分塊上傳、暫停/續傳Fine Uploader、Dropzone.js、Uppy、FilePondMultipartFormDataStreamProvider 流式處理,不佔用大量記憶體<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 GB | 50 MB | 3-5 | 小型專案 |
| 4 GB | 100 MB | 5-8 | 中型專案 |
| 8 GB+ | 200-500 MB | 10+ | 需搭配分塊上傳 |
超過建議值易導致 OutOfMemoryException 或請求佇列堵塞。企業級系統必須實作分塊上傳 (Chunked Upload):前端將大檔切割 1-5 MB 片段,後端暫存合併,單次請求體積可控。
PostedFile.ContentType)ASP.NET FileUpload 大檔上傳核心在於 web.config 雙重設定 (httpRuntime.maxRequestLength + requestFiltering.maxAllowedContentLength) 與 executionTimeout 調整。超過限制的 400 錯誤無法用 try-catch 捕獲,必須透過 customErrors 導向專用錯誤頁面友善提示。現代專案強烈建議採用 HTML5 非同步分塊上傳架構,徹底解決記憶體、逾時、使用者體驗三大痛點。