MVC 將檔案上傳DB(SQL SERVER)、從DB(SQL SERVER)下載

  • 3417
  • 0
  • MVC
  • 2019-06-26

在MVC的架構底下,將文字檔上傳並存到SQL SERVER的DB內

實作在MVC的架構底下上傳檔案到SQL SERVER的DB內,上傳成功之後要可以下載

先點選左邊的選擇檔案來選擇檔案,然後再點選右邊按鈕將檔案上傳至DB,上傳成功之後最右邊有一個連結可以點選並下載剛剛上傳成功的檔案

DB裡面的欄位會這樣開:

主要就是FILE_NAME跟FILE_DATA這兩個欄位

HTML:

<div class="form-group">
	<label class="control-label col-md-2" for="AP_Upload">說明文件:</label>
	<div class="col-md-6">
		<input class="form-control-file" id="AP_Upload" style="width: 500px;padding-top:7px;" type="file">
	</div>
	<div class="col-md-4">
		<button class="btn btn-mega btn-sm" id="btnFileUploadFirst" type="button">檔案上傳</button>
		@Html.HiddenFor(Model => Model.APCondition.AP_UPLOAD_ID_1, new { @id = "hidAP_UPLOAD_ID_1" })
		@Html.HiddenFor(Model => Model.APCondition.strUploadFileName_1, new { @id = "hidUploadFileName_1" })
		<a id="btnDownLoadFirst" style="cursor: pointer;" href="" target="_blank"></a>
	</div>
</div>

1.type = file 的<input> :提供選擇檔案上傳

2.兩個Hidden的欄位:

hidAP_UPLOAD_ID_1 是存在DB內的PK

strUploadFileName_1: 上傳檔案的文件名稱

3.<a> 是提供使用者點選檔案下載的連結(如果有上傳成功的話)

JS:

/*
刻意設為全域變數,在#AP_Upload change事件的時候就要將要上傳的資料放到
這兩個變數內,但是在點選檔案上傳按鈕的時候才會真的使用到這兩個變數內資料
*/
var _UploadObject_One = new FormData();
var UploadFileName =
    {
        FileOne: ''
    }



//初始化業務系統說明文件上傳、特殊設定說明文件
function InitialFileUpload() {

    var _FileName = $.trim($('#hidUploadFileName_1').val()),
        _AP_UPLOAD_ID_1 = $.trim($('#hidAP_UPLOAD_ID_1').val());

    //修改模式下,如果已經有上傳過檔案,要將檔名跟路徑設好,讓使用者可以下載文件預覽
    if (_FileName != '') {
        $('#btnDownLoadFirst').text(_FileName);
        var _href = $('#btnDownLoadFirst').attr('href');
        _href = "../AP/DownloadFile?AP_UPLOAD_ID=" + encodeURI(_AP_UPLOAD_ID_1) + "&FileName=" + encodeURI(_FileName);
        $('#btnDownLoadFirst').attr('href', _href);
    }


    //系統說明文件 選擇檔案 Change事件,
	//利用Change事件將要上傳的檔案資訊塞到上面設定的兩個全域變數內
    $('#AP_Upload').on('change', function (e) {
        //取得檔案
        var files = e.target.files;
        
        if (files.length > 0) {
            if (window.FormData !== undefined) {                
                //可上傳多檔案
                //for (var x = 0; x < files.length; x++) {
                //    data.append("UploadFile", files[x]);
                //}
				
				//限制檔案大小20M
				var FileSize = files[0].size / 1048576; //size in mb 
                if (FileSize > 20) {
                    alert('檔案大小不得超過20M,請重新選擇檔案!');
                    $('#AP_Upload').val('');
                    return false;
                }
                
				//取得副檔名
				//Commonutility.GetFileExtension 下面會再補充說明
                var FileExtension = Commonutility.GetFileExtension(files[0].name); 
                if (FileExtension == 'txt' || FileExtension == 'doc')
                {
                    //因為IE11 不支援Formdata.get,所以先判斷是否undefined
                    if (_UploadObject_One.get != undefined) {
                        if (_UploadObject_One.get("UploadFile") == null) {
							//_UploadObject_One沒設定過UploadFile,可直接Append
                            _UploadObject_One.append("UploadFile", files[0]);
                        }
                        else {
                            _UploadObject_One.delete('UploadFile');
                            _UploadObject_One.append("UploadFile", files[0]);
                        }
                    }
                    else {
                        //IE 不支援Formdata.get、也不支援delete,所以直接append就好,檔案會後蓋前
                        _UploadObject_One.append("UploadFile", files[0]);
                        UploadFileName.FileOne = files[0].name;
                    }
                }
                else {
                    alert('請上傳正確文字檔檔案');
                    $('#AP_Upload').val('');
                    return false;
                }
            } else {
                alert("此瀏覽器不支援HTML5檔案上傳");
            }
        }
    });

    //業務系統說明文件檔案上傳
    $('#btnFileUploadFirst').on('click', function () {
        if (window.FormData !== undefined) {

            //IE 只要選過資料以後,按取消鍵也不會檔案消失
            if ($.trim($('#AP_Upload').val()).length === 0) {
                alert('請先選擇資料再點選上傳!');
                return false;
            }

            $.ajax({
                type: "POST",
                url: '../AP/APFileUpload',
                async: false,
                contentType: false,
                processData: false,
                data: _UploadObject_One,
                success: function (_result) {
                    if (_result.ReturnCode == '000') {
                        alert('檔案上傳成功!');
                        
                        var _FileName = '';

                        //IE 不支援Get
                        if (_UploadObject_One.get != undefined) {
                            _FileName = _UploadObject_One.get("UploadFile").name;
                        }
                        else {
                            _FileName = UploadFileName.FileOne;
                        }
                        $('#btnDownLoadFirst').text(_FileName);

                        //存 文件上傳到回來的PK
                        $('#hidAP_UPLOAD_ID_1').val(_result.ReturnMessage);

                        var _href = $('#btnDownLoadFirst').attr('href');
						//因為要傳送檔名(可能有中文),所以要 encodeURI
                        _href = "../AP/DownloadFile?AP_UPLOAD_ID=" + encodeURI(_result.ReturnMessage) + "&FileName=" + encodeURI(_FileName);
						
                        $('#btnDownLoadFirst').attr('href', _href);
                    }
                    else {
                        alert(_result.ReturnMessage);                        
                    }
                },
                error: function (error) {
                    alert('error; ' + error);
                }
            });
        } else {
            alert("此瀏覽器不支援HTML5檔案上傳");
        }
    });
}

//補充說明
//取得副檔名 參考來源:http://www.jstips.co/zh_tw/javascript/get-file-extension/
var GetFileExtension = function(filename) {
	return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
}
Commonutility.GetFileExtension = GetFileExtension;

限制檔案上傳大小20M,除了在前端限制之外,

Webconfig也要改,預設只能上傳4M

要改的地方有兩個(VS2015)

分別是在 <sysytem.web>底下、<system.webServer>

<!-- maxRequestLength for asp.net, in KB Add By H20 修改檔案上傳的限制,上限調整為20M -->
<httpRuntime targetFramework="4.5.2" maxRequestLength="20480"/>


<security>
  <requestFiltering>
	<!-- maxAllowedContentLength, for IIS, in bytes Add By H20 修改檔案上傳的限制,上限調整為20M-->
	<requestLimits maxAllowedContentLength="20971520" ></requestLimits>
  </requestFiltering>
</security>

controller這邊有兩段

第一段是檔案上傳的部分

[HttpPost]
public ActionResult APFileUpload()
{
	ResultObject _resultObject = new ResultObject();

	// 取得目前 HTTP 要求的 HttpRequestBase 物件
	foreach (string file in Request.Files)
	{
		var fileContent = Request.Files[file];
		if (fileContent != null && fileContent.ContentLength > 0)
		{
			// 取得的檔案Type:stream
			var stream = fileContent.InputStream;
			var fileName = Path.GetFileName(file);

			//檔案類型
			String MimeType = fileContent.ContentType;

			#region Copy 檔案到指定路徑底下
			//var path = Path.Combine(Server.MapPath("~/Files/"), fileName);
			//using (var fileStream = System.IO.File.Create(path))
			//{
			//    stream.CopyTo(fileStream);
			//}
			////如果有COPY檔案的話要歸零
			//stream.Position = 0;
			#endregion

            //EF要存檔的物件,參考就好
			AP_UPLOAD_FILE _ap_upload = new AP_UPLOAD_FILE();


			byte[] buffer = new byte[20 * 1024*1024];

			using (MemoryStream ms = new MemoryStream())
			{
				int read;
				while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
				{
					ms.Write(buffer, 0, read);
				}
				_ap_upload.FILE_DATA = ms.ToArray();

			}

			_ap_upload.AP_UPLOAD_ID = Common_Utility.GetApplyID("AP", "900");//取得PK
			_ap_upload.CATEGORY = "1";
			_ap_upload.MIME_TYPE = MimeType;//檔案類型
			_ap_upload.FILE_NAME = fileContent.FileName;//檔案名稱
			_ap_upload.CRT_DATE = DateTime.Now;


			try
			{
				db.AP_UPLOAD_FILE.Add(_ap_upload);
				db.SaveChanges();
				_resultObject.ReturnCode = "000";
				_resultObject.ReturnMessage = _ap_upload.AP_UPLOAD_ID;
			}
			catch (Exception ex)
			{
				_resultObject.ReturnCode = "999";
				_resultObject.ReturnMessage = ex.InnerException.InnerException.Message;
			}
		}
	}

	return Json(_resultObject);
}

第二段Controller是檔案下載的部分

public ActionResult DownloadFile(String AP_UPLOAD_ID = null, String FileName = null)
{
	//在前端JS要傳資料到後端的時候有用encodeURI去加密要傳送的資料
	//所以這邊要用System.Uri.UnescapeDataString 解密
	String _AP_UOLOAD_ID = System.Uri.UnescapeDataString(AP_UPLOAD_ID);
	String _FileName = System.Uri.UnescapeDataString(FileName);

	var query = (from p in db.AP_UPLOAD_FILE.AsQueryable()
					 where p.AP_UPLOAD_ID == AP_UPLOAD_ID
					 select new
					 {
						 MIME_TYPE = p.MIME_TYPE, //檔案類型
						 FILE_DATA = p.FILE_DATA  //檔案內容
					 }).FirstOrDefault();

	if (query != null)
	{
		return File(query.FILE_DATA, query.MIME_TYPE, FileName);
	}
	return View();
}

DownloadFile.cshtml 就不需要加任何東西,純粹檔案下載用

以上,謝謝