[asp.net mvc][jquery]簡易實做檔案上傳(支援多個檔案)

  • 772
  • 0
  • 2022-11-02

[asp.net mvc][jquery]簡易實做檔案上傳(支援多個檔案)

.cshtml:
其實就是用input type = 'file'

<input type="file" id="fileUpload" multiple>
<button class="btn btn-success" id="btnSave" onclick="Save()">儲存</button>


<input type="hidden" id="hidAppPath" value="@Url.Content("~/")" />
<!--應用程式根目錄路徑-->


javascript:

//上傳檔案的base64
var uploadFileDetailArr = [];
var uploadFileIndex = 0;

//存檔
function Save() {
    uploadFileIndex = 0;
    uploadFileDetailArr = [];
    WaitFileToArrThenPost($('#fileUpload').get(0).files.length);  
}

//等候檔案轉換為base64格式完畢
function WaitFileToArrThenPost(targetLength) {
    
    console.log('target file array length:' + targetLength);

    if (uploadFileDetailArr && uploadFileDetailArr.length < targetLength) {
        var fileUploadEle = $('#fileUpload').get(0);
        var reader = new FileReader();
        reader.readAsDataURL(fileUploadEle.files[uploadFileIndex]);
        reader.onload = function () {
            console.log(reader.result);
            var fileName = fileUploadEle.files[uploadFileIndex].name;
            var fileType = fileUploadEle.files[uploadFileIndex].type;
            var pushFileObj = {
                FileName: fileName,
                FileType: fileType,
                FileContentBase64: reader.result,
            };
            uploadFileDetailArr.push(pushFileObj);
            uploadFileIndex++;
            setTimeout(() => {
                WaitFileToArrThenPost(targetLength, funcName);
            }, 100);
        };
        
        /* 每隔1000 milliseconds會檢查一次flag狀態是否變化*/

        console.log("等候檔案轉換為base64格式中...");
    } else {
        /* do something*/
        console.log("等候檔案轉換為base64格式完畢!");
        var formJSON = FormToJSON();
        console.log('formJSON:');
        console.log(formJSON);
        SavePost(formJSON);
        
    }
}


function SavePost(formJSON) {
    var appPath = $("#hidAppPath").val();
    console.log('送出之前顯示:');
    console.log(formJSON);
    $.ajax({
        type: 'POST',
        url: appPath + 'MyController/SavePost/',
        data: formJSON,
        //data: JSON.stringify({ SaveDataList: saveArr }),
        //這是回傳多筆JSON資料的情況
        success: function (resultData) {
            if (resultData.IsSuccess == true) {
                alert('存檔成功!');
                
            }
            else {
                console.log(resultData.ErrorMsg);
                alert('出現意料之外的錯誤,請查看F12的writeLog()紀錄。');
            }

        },

        error: function (error) {
            console.log(error);
            alert('出現意料之外的錯誤,請查看F12的writeLog()紀錄。');
        },

    });
}

 

Controller的c#程式碼:

[HttpPost]
//存檔
public ActionResult SavePost(AuditCorrectSavePostModel model)
{
    if (model == null)
    {
        return Json(new EmptyResult());
    }
    AuditCorrectDbContext dal = new AuditCorrectDbContext();
    var saveResult = dal.SavePost(model);         

    if(saveResult.IsSuccess)
    {
        //儲存上傳的檔案到硬碟
        saveResult = SaveUploadFiles(saveResult, model);                
    }
    
    //回傳Json資料			
    return Json(saveResult);


}

 //儲存上傳的檔案到硬碟
private ModalFormSaveResultModel SaveUploadFiles(ModalFormSaveResultModel saveResult, AuditCorrectSavePostModel model)
{
    if (saveResult.IsSuccess)
    {
        if (model.UploadFileDetailArr != null && model.UploadFileDetailArr.Length > 0)
        {
            try
            {
                //目錄不存在則建立
                //目錄已存在則先刪除裡面的檔案
                string fileDir = Path.Combine(Server.MapPath(UploadPath
                        + saveResult.InfoObj.UploadFilePath));
                if (Directory.Exists(fileDir) == false)
                {
                    Directory.CreateDirectory(fileDir);
                }
                else
                {
                    foreach (var file in Directory.GetFiles(fileDir))
                    {
                        System.IO.File.Delete(file);
                    }
                }
                //寫入檔案到硬碟
                foreach (UploadFileDetailModel uploadFileDetail in model.UploadFileDetailArr)
                {
                    string _FileName = uploadFileDetail.FileName;
                    string _path = Path.Combine(fileDir, _FileName);

                    Byte[] bytes = Convert.FromBase64String(uploadFileDetail.FileContentBase64.Split(',')[1]);

                    System.IO.File.WriteAllBytes(_path, bytes);
                }
            }
            catch (Exception ex)
            {
                saveResult.IsSuccess = false;
                saveResult.ErrorMsg = "db存檔已成功,但上傳檔案過程發生錯誤:" + ex.ToString();
            }

        }
    }

    return saveResult;
}

 

Model的c#類別:

//存檔完畢之後回傳結果的物件
public class ModalFormSaveResultModel
{
    public bool IsSuccess { get; set; } = false;
    public string ErrorMsg { get; set; } = string.Empty;
    public string InfoMsg { get; set; } = string.Empty;
   
}

//按下(存檔)按鈕時,post送出的資料
public class AuditCorrectSavePostModel
{   
    public UploadFileDetailModel[] UploadFileDetailArr { get; set; }//多個檔案上傳

}

public class UploadFileDetailModel
{
    public string FileName { get; set; }
    public string FileType { get; set; }
    public string FileContentBase64 { get; set; }

}

 


 執行結果:

 


這篇大概是這樣……

ps.補充:如果是大型檔案上傳,請在web.config加入以下的maxRequestLength以及maxAllowedContentLength屬性,這邊的範例可以讓你上傳1G大小左右的檔案:

<system.web>
    <compilation debug="true" targetFramework="4.8" />
    <httpRuntime targetFramework="4.8"  maxRequestLength="1048576"  />
    <customErrors mode="Off"/>
</system.web>
<system.webServer>
	<security>
		 <requestFiltering>
			<!-- 大小限制 1G -->
			<requestLimits maxAllowedContentLength="1073741824" />
		 </requestFiltering>
	</security>
</system.webServer>


ps.補充說明:本文說明上傳的方法,常常會與(如何實做下載)這篇文章一起參考喔,因為專案中通常上傳之後,使用者也要用到下載功能

參考資料:
Upload Files In ASP.NET MVC 5 (c-sharpcorner.com)
在網頁應用程式中使用本地檔案 - Web APIs | MDN (mozilla.org)