.Net MVC 透過ajax實做檔案上傳
Hi 好久不見了。。。換了新的公司,迷失了一陣子。
新的公司都是用.net MVC3 進行開發。
我之前完全沒開發過,唯獨上過保哥的課程,憑藉著之前寫WebForm的經驗開始了這趟旅程。
大致上,是沒有什麼問題,只是,View的撰寫技巧還需要再加強。
一天加班要下班時,發現一個同事好像困擾著什麼,抱著雞婆的心態問了一下。
他說,他要寫個功能,但不知道怎麼實踐。
主要時:使用者成功做完A之後,要呈現A成功的畫面,同時A畫面下面要有一個上傳檔案的功能,
上傳成功後,除了A畫面要保留,還要有上傳檔案的內容呈現在下方。
我當下幫他想了幾個方案,都以已經完成A僅要處理B的方案:
- 透過Submit方式,檔案傳送到B的Action接收,B的Action Return的View要包含,A&B的內容。
- 透過AJAX,傳送到B的Action,B回傳Partial View。(這條實在不確定是否可行)。
- 全部都透過AJAX,檔案傳送到B的Action,B回傳一個Json(檔案內容)
方案都想完了,也跟同事說了,同事說他再想一想,
結果,我告訴他一個事實,我不知道怎麼在MVC的世界做檔案上傳這個動作。
回家覺得不該只出一張嘴,所以產生這篇文章。
最後,我決定透過第三個方案來做,因為1感覺這樣又跟以前WebForm一樣,每次Post,都是所有東西都丟給Server,Server又把所有東西再丟回去。
2的話,沒信心搞定,所以,最終究走第三條拉。。
網路上Google其實,已經有幾乎百分之百的答案,但,我們還是理解&改造成更貼近自己的需求吧!
先看畫面部分:
<div>
<input id="fileUpload" type="file" />
<input id="btnUploadFile" type="button" value="Upload File" />
</div>
畫面很簡單吧!!一個Div放置結果,一個上傳檔案input,一個上傳的Button。
接著,我們先看Controller:
public virtual ActionResult UploadFile()
{
//## 如果有任何檔案類型才做
if (Request.Files.AllKeys.Any())
{
//## 讀取指定的上傳檔案ID
var httpPostedFile = Request.Files["UploadedImage"];
//## 真實有檔案,進行上傳
if (httpPostedFile != null && httpPostedFile.ContentLength != 0)
{
httpPostedFile.SaveAs("E:\\");
}
}
//## 模擬上傳的檔案內容
List<Test> oStr = new List<Test>();
oStr.Add(new Test() { ID = 1, Name = "王1" });
oStr.Add(new Test() { ID= 2,Name= "王2" });
//## 將結果回傳
return Json(new { isUploaded = true, result = oStr }, "text/html");
}
相信註解寫的夠清楚拉!!接著我們看AJAX這段。本範例是透過Jquery達成。
//## 按下上傳按鈕觸發
$('#btnUploadFile').on('click', function () {
//## 宣告一個FormData
var data = new FormData();
//## 將檔案append FormData
var files = $("#fileUpload").get(0).files;
if (files.length > 0) {
data.append("UploadedImage", files[0]);
}
//## 透過ajax方式Post 至Action
var ajaxRequest = $.ajax({
type: "POST",
url: "@Url.Action("UploadFile")",
contentType: false, // 告诉jQuery不要去這置Content-Type
processData: false, // 告诉jQuery不要去處理發送的數據
dataType: "json",
data: data
})
.done(function (data, textStatus) {
//## data 接收回傳的Json,透過each組合結果
var htmlresult="<ul>";
$.each(data.result, function (i, item) {
htmlresult += "<li>" + item.ID + ":" + item.Name + "</li>";
});
htmlresult += "</ul>";
//## 將結果append到預留的DIV中
$("#DivResult").append(htmlresult);
})
.fail(function() {
alert( "error" );
});
});
});
註解也寫的頗清楚了,我猜。
這邊因為我對於Javascript世界中的FormData一隻半解,又在查了一下。
有興趣的請看:https://developer.mozilla.org/zh-CN/docs/Web/Guide/Using_FormData_Objects
針對Jquery的設置也可以看一下StackOverflow的解答。
早在2011就有人發問了,現在都2014了呢!!
最後隔天給了同事我寫的程式碼&跟他講解,最後他好像也完成了這樣一件工作。。。。
我寫程式多數原因是:薪水。。。。
但,做這件事情是熱情 & 當你看到你幫助了人的那種快樂,還有少部分的覺得丟臉而努力去學。
我說過一句話:現在的程式設計師八成是靠著Google來的解答,只有兩成是寫給人Copy的解答。
我希望總有一天,我也是那兩成中的其中一人。。。。。
參考資料:
http://www.codeproject.com/Articles/806075/File-Upload-using-jQuery-AJAX-in-ASP-NET-Web-API
http://powerdotnetcore.com/asp-net-mvc/asp-net-mvc-simple-ajax-file-upload-using-jquery