.NET6 Web Api 檔案下載同時取得檔名
.NET6, Download File, Content-Disposition, ContentDisposition
引言
為工作紀錄。找到一個比較標準的答案在下載檔案時同時也取得檔名。
主要參考文章
下載檔案
下載檔案同時送回檔名:Content-Disposition
這個Content-Disposition
為一個 Response Header 屬性之一。用來把附件檔名等資訊送回去前端,此機制在歷經多年後已變成標準了。標準格式如下例:
因為多國語語有字型編碼的問題,固再加入一個 "filenam*" 屬性並有UTF-8與URL編碼,如下例子:
可用decodeURI
指令來解碼得出檔名,如下圖例:

參考關鍵字文件,更多說明請膜拜google大神。這裡以紀錄為主。
程式碼紀錄
後端:Web API in .NET6
using Microsoft.AspNetCore.Mvc;
namespace YourProject.Controllers;
[ApiController]
[Route("api/[controller]/[action]")]
public class FileController : ControllerBase
{
[HttpPost]
public IActionResult DownloadFile()
{
FileInfo fi = new FileInfo(@"Template/MinIO 評估.docx");
byte[] blob = System.IO.File.ReadAllBytes(fi.FullName);
return File(blob, System.Net.Mime.MediaTypeNames.Application.Octet, fi.Name);
//※ 其中 FileContentResult 第3個參數會產生 Content-Disposition 的 Response Header 把檔名編碼後送到前端。
}
}
前端:React.v18
import { saveAs } from 'file-saver'
function handleDownloadFile() {
const url = 'api/File/DownloadFile'
const options = {
method: 'POST',
};
let fileName = 'unknown.bin'
fetch(url, options)
.then(resp => {
if (!resp.ok) throw new Error('Network response was not ok.');
// 解析附件檔名
const contentDisposition = resp.headers.get('content-disposition') as string
fileName = decodeURI(contentDisposition.split("filename*=UTF-8''")[1])
return resp.blob();
})
.then(blob => {
saveAs(blob, fileName)
});
}
組態:可能會有 CORS (Cross-Origin Resource Sharing)預設限制把 Content-Disposition 過濾掉,必須設定成可以通過:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
options.AddDefaultPolicy(policy =>
policy.WithExposedHeaders("Content-Disposition")
//※ 讓 FileContentResult 可以回傳檔名。預設被過濾掉。
));
...省略...
var app = builder.Build();
...省略...
app.UseRouting();
app.UseCors();
...省略...
EOF
Last updated