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

ASP.NET MVC 文件下載實戰:FileResult 返回瀏覽器原生下載對話框與檔名編碼處理

     編輯:關於ASP.NET

利用瀏覽器內建下載功能,透過 FileResult 系列返回檔案流,自動觸發「另存新檔」對話框。本文涵蓋實體檔案、記憶體流、大檔案分塊、中文檔名編碼、Content-Disposition 標頭完整處理。

最簡單用法:返回實體檔案

public ActionResult Download() {
    var path = Server.MapPath("~/Files/report.pdf");
    return File(path, "application/pdf", "報表.pdf"); // 瀏覽器彈出下載,檔名「報表.pdf」
}

瀏覽器下載對話框截圖

FileResult 家族

類型適用場景建構參數
FilePathResult磁碟實體檔案File(path, contentType, fileName)
FileContentResult記憶體位元組陣列File(byte[], contentType, fileName)
FileStreamResult任意 Stream (大檔、網路流、壓縮流)File(stream, contentType, fileName)
PhysicalFileResultCore 專用,支援 Range 請求 (斷點續傳)PhysicalFile(path, contentType, fileName)
VirtualFileResultCore 專用,虛擬路徑 (IFileProvider)File(virtualPath, contentType, fileName)

中文檔名編碼:RFC 5987 / RFC 6266 相容寫法

public ActionResult DownloadWithChineseName() {
    var path = Server.MapPath("~/Files/報表.pdf");
    var fileName = "報表.pdf";
    var encodedFileName = Uri.EscapeDataString(fileName); // UTF-8 百分號編碼
    var cd = new ContentDisposition {
        FileName = fileName,                    // 兼容舊瀏覽器 (IE)
        FileNameStar = $"UTF-8''{encodedFileName}" // RFC 5987: 現代瀏覽器
    };
    Response.AppendHeader("Content-Disposition", cd.ToString());
    return File(path, "application/pdf");
}

大檔案優化:FileStreamResult + 緩衝輸出

public ActionResult DownloadLargeFile() {
    var path = Server.MapPath("~/Files/big.iso");
    var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan);
    // SequentialScan 提示 OS 循序讀取,減少緩衝區污染
    return File(stream, "application/octet-stream", "big.iso");
}
// 注意:Stream 由 MVC 管線自動 Dispose,無需手動 using

斷點續傳 / Range 請求支援 (ASP.NET Core)

[HttpGet]
public IActionResult DownloadRange(string file) {
    var path = _env.ContentRootFileProvider.GetFileInfo(file).PhysicalPath;
    return PhysicalFile(path, "application/octet-stream", file, enableRangeProcessing: true);
    // 自動處理 Request.Headers["Range"],返回 206 Partial Content
}

動態生成檔案:記憶體流 + 即時壓縮

public ActionResult ExportExcel() {
    using (var ms = new MemoryStream()) {
        using (var pkg = new ExcelPackage(ms)) {
            var ws = pkg.Workbook.Worksheets.Add("Data");
            ws.Cells[1,1].Value = "Hello";
            pkg.Save();
        }
        ms.Position = 0;
        return File(ms.ToArray(), 
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 
            "Export.xlsx");
    }
}

安全與效能檢查清單

  • ✅ 路徑遍歷防護:Path.GetFullPath(path).StartsWith(allowedRoot),拒絕 ../../etc/passwd。
  • ✅ MIME 型別白名單:禁止 application/x-msdownload、text/html 等可執行/腳本類型。
  • ✅ 大檔案不進記憶體:使用 FileStreamResult / PhysicalFileResult,避免 byte[] 導致 LOH 壓力。
  • ✅ 速率限制:單 IP/用戶下載頻率、帶寬節流。
  • ✅ 審計日誌:記錄下載者、檔案、時間、IP、User-Agent。

瀏覽器相容性備註

  • Chrome/Edge/Firefox:完美支援 FileNameStar (UTF-8)。
  • IE 11:僅支援 FileName (需 URL 編碼),FileNameStar 會被忽略。
  • Safari:支援 FileNameStar,但舊版可能需 filename*=UTF-8''... 格式。
  • 舊版移動瀏覽器:可能直接在瀏覽器顯示而非下載,需確保 Content-Type 非文字類型、Content-Disposition: attachment。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved