[技術探討]ASP.Net MVC動態檔案上傳 實作

MVC檔案上傳

MVC概述
最近公司開始進行 MMS簡訊 發送平台的開發,網頁部分開始用MVC進行開發,對我來說是一個全新的領域,MVC的概念是將網頁的結構分為三個部分,分別為Model、View、Controller三個部分,其中Model指的是資料的部分,包括資料庫的存取以等等的工作。View指的是視覺的部分,常見的HTML、JavaScript、CSS都是包含在View裡面。最後Controller則是控制整個網頁流程的部分,是主要負責邏輯處理的部分。

MVC動態檔案上傳

由上圖可以簡單說明MVC的運作,當使用者在Browser操作UI時,Browser會傳遞Request給所指定的Controller,這個階段的動作可稱作Routing,這收到Request的Controller會依照所設定的流程運作決定下一個動作,當如果只是回傳導向網址之類的小動作,Controller就會直接將動作回傳給View,接著就會呈現在Browser上。如果Controller必須跟資料庫取得資料或是要進行資料的驗證,就必須透過Model進行交涉,最後再透過Model回傳資料給Controller,最後傳遞給View及Browser。MVC的運作擺脫了Web Form 複雜的生命週期,讓Web的運作更透明化,更容易進行管理。

 

利用JQuery實現動態上傳介面

由於MMS簡訊可以傳送多個多媒體檔案,所以我很苦惱到底如何讓使用者可以有次序的上傳多個檔案,但是到底要上傳幾個檔案呢?總不能只寫了2個上傳標籤<File Upload Input Tag>然後讓使用者看著辦吧,萬一他要上傳3個檔案呢?最後我想到,利用JQuery動態的產生上傳標籤,由示意圖可看到當按下”+”按鈕,就會新增一個新的上傳標籤,按下”-“按鈕就會去除一個上傳標籤,其中的方法是我利用了@Html.Hidden去紀錄目前頁面上的所有的上傳標籤數目,再利用JQuery的function $(document.createElement()),增加頁面的標籤,達成動態產生上傳標籤的目的。

MVC動態檔案上傳

MVC動態檔案上傳 MVC動態檔案上傳

JQuery部分的程式碼如下

<script type="text/javascript">
    $(document).ready(function () {
        $("#addButton").click(function () {
            var currentCount = parseInt($('#FileCount').val(), 10);
            var newCount = currentCount + 1;
            var newColumnDiv = $(document.createElement('div')).attr("class", 'col-md-10');
            var newTextBoxDiv =
                $(document.createElement('div')).attr(
                {
                    "id": 'FileDiv' + newCount,
                    "class": "form-group"
                });
            newTextBoxDiv.appendTo(newColumnDiv);
            newTextBoxDiv.after().html(
                '<label>Upload #' + newCount + ' : </label>' +
                '<input type="file"' +
                ' name="file' + newCount + '" id="file' + newCount + '"' +
                ' value=""  class="btn btn-default">');
            newColumnDiv.appendTo("#FileGroup");
            $('#FileCount').val(newCount);
        });
        $("#removeButton").click(function () {
            var currentCount = parseInt($('#FileCount').val(), 10);
            if (currentCount == 0) {
                alert("操作錯誤!");
                return false;
            }
            $("#FileDiv" + currentCount).remove();
            var newCount = currentCount - 1;
            $('#FileCount').val(newCount);
        });
    });
</script>

View的部分程式碼如下

<div class="well" role="form">
	<div class="row" id="FileGroup">
		<div class="col-md-10">
			<div id="FileDiv1" class="form-group">
				<label>Uplaod #1 : </label>
				<input type="file" name="file1" id="file1" class="btn btn-default" />
			</div>
		</div>
	</div>
	@Html.Hidden("FileCount", 1)
	<input type="button" class="btn btn-default" value="+" id='addButton'>
	<input type="button" class="btn btn-default" value='-' id='removeButton'>
	<input type="submit" class="btn btn-default" value="Upload" />
</div>

Controller 使用Request.Files取得上傳的檔案

在Controller要取得上傳檔案的的時候通常會使用HttpPostedFileBase來取得檔案,但是要使用HttpPostedFileBase來擷取檔案必須要知道上傳標籤裡面Name屬性的參數,並不適用在這個動態產生的上傳標籤,所以使用Request.Files來取得上傳的檔案,其部分程式碼如下。

foreach (string file in Request.Files)
{
	HttpPostedFileBase uploadFile = Request.Files[file] as HttpPostedFileBase;
	if (uploadFile != null && uploadFile.ContentLength > 0)
	{
		var fileName = Path.GetFileName(uploadFile.FileName);
		var path = Path.Combine(@"D:\Test", fileName);
		uploadFile.SaveAs(path);
		string FileType = uploadFile.ContentType;
	}
}

當我們按下Upload按鈕時,會將要上傳的檔案資訊Post到Controller,利用Request.Files 可以取都所有檔案資訊,其類型為HttpFileCollection物件,表示上傳檔案的集合,在程式碼中可以看到”uploadFile.ContentLength>0”,利用ContentLength屬性來判斷上傳的檔案是否有內容,如果檔案沒內容上傳也沒意思,反而增加困擾,所以我就很直接的過濾掉了,再來”.FileName”,可以取得上傳檔案的檔案名稱,” .ContentType”可以取得檔案的類型及附檔名(image/.jpg),”.SaveAs()”就是把檔案存到指定路徑。用Request.Files可以很輕鬆的將整個頁面上所有的檔案一次擷取存檔,不用一個個去設定上傳標籤裡面的Name屬性,可以省去不少的苦功,是一個很不錯的方法。

結論

在這次MMS簡訊發送平台的開發是我第一次使用MVC進行開發,相較於Web Form的生命週期,我覺得MVC還是比較清楚明白一點,但是要學的還很多,希望能早早脫離撞牆期,我相信一定還有很多各式各樣的方可以解決類似這種動態多檔案上傳的功能,能有新的方法解決問題這才是寫程式有趣的地方啊!


發佈留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料