ASP.NET MVC 5 實作多檔案 / 複數檔案上傳功能 (ASP.NET MVC Upload Multiple Files)
2022-04-09
筆記 ASP.NET MVC 如何實作多檔案與複數檔案的上傳功能,讓使用者可以批次上傳檔案,不再需要逐一上傳囉,使用者體驗 Up 😲
說明
Model
FiledUploaded.cs
using System.IO
public class FiledUploaded
{
public FiledUploaded(HttpPostedFileBase file, string serverPath)
{
HashedName = System.Web.Helpers.Crypto.SHA256(file.FileName);
FileName = file.FileName;
FileSize = file.ContentLength;
ServerPath = Path.Combine(serverPath + file.FileName);
Extension = Path.GetExtension(file.FileName);
}
public string FileName { get; set; }
public string HashedName { get; set; }
public string ServerPath { get; set; }
public int FileSize { get; set; }
public string Extension { get; set; }
}
Controller
示範是使用同名 Action Upload
並以 GET Method 以及 POST Method 區別顯示的內容,如果是 POST Method 就顯示上傳的檔案內容。
多檔案上傳在 Conroller 的靈魂所在為 POST Method 參數要使用
public ActionResult Upload()
{
return View();
}
[HttpPost]
public ActionResult Upload(HttpPostedFileBase[] files)
{
// Check If Upload Nothing
if (files[0] == null)
{
return RedirectToAction("Upload");
}
var fileUploads = new List<FiledUploaded> { };
foreach (var file in files)
{
var fileUpload =
new FiledUploaded(file, Server.MapPath("~/Uploads/"));
file.SaveAs(fileUpload.ServerPath);
fileUploads.Add(fileUpload);
}
return View(fileUploads);
}
View
在 View 當中,多檔案上傳的靈魂於在於 File Input 必須要有 multiple
屬性,如此一來 Browser 就會允許使用者選擇多個檔案進行上傳。
Upload.cshtml
@model IList<MVCTemplate.Controllers.FiledUploaded>
@{
ViewBag.Title = "Upload Features";
}
@using (
Html.BeginForm(
"Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })
)
{
<div class="mb-1">
<label for="formFile" class="form-label">上傳檔案</label>
@Html.TextBox("files", "",
new { type = "file", multiple = "multiple", @class = "d-block" })
<br />
</div>
<div class="mb-3 d-flex">
<ion-icon name="cloud-upload-outline" style="font-size: 2rem"></ion-icon>
<input type="submit"
value="上傳"
class="btn btn-primary ml-3"
id="uploadBtn"
disabled />
<br />
</div>
}
本次範例上傳元件與上傳結果是相同頁面,因此利用 HTTP Method 判斷是否為 POST 以顯示上傳檔案的名稱及相關資訊
@if (Context.Request.HttpMethod == "POST")
{
<div class="row mb-5">
@foreach (var file in Model)
{
<div class="col-4 d-flex mb-3">
<div class="card">
<div style="overflow: hidden; height: 200px">
<img class="card-img-top" src="~/uploads/@file.FileName">
</div>
<div class="card-body">
<h5 class="card-title">@file.FileName</h5>
<p class="card-text">
@(file.FileSize / 1024) KB
</p>
<a href="#" class="btn btn-outline-danger">Like</a>
</div>
</div>
</div>
}
</div>
}
預設上使用者沒有選擇任何檔案也可以看上傳,雖然在後端 Action 有進行檢查,但在前端能夠防呆會讓使用者體驗更好,所以在 Upload 的 Submit Button 啟用 Disabled 屬性,並且使用 jQuery 偵測選擇上傳的檔案數合理時,才主動移除 Disabled 屬性。
同時也檢查如果使用者又調整為不上傳任何檔案時,自動為 Submit Button 加入 Disabled 屬性。
@section scripts{
<script>
$(document).ready(function () {
$('#files').change(function(){
if ($('#files')[0].files.length > 0) {
$('#uploadBtn').removeAttr('disabled');
}
else {
$('#uploadBtn').attr('disabled', true)
}
})
})
</script>
}
精進作為
本篇主要是探討如何實作多檔案上傳,對於 Web 安全性的細節實作還有強化的空間,有興趣的朋友可以參考單檔上傳時的 Safer Practices ASP.NET MVC 5 實作更安全的檔案上傳功能 (ASP.NET MVC Safer File Upload Implements) 並加以應用在多檔案上傳 😀
參考資料
Vithal Wadje 在 C# Cornoer 所分享的Uploading Multiple Files In ASP.NET MVC