2013年3月24日 星期日

ASP.NET MVC - 使用 jQuery Form Plugin 做檔案上傳

之前曾經介紹過使用 file-uploader 來做 Ajax 的檔案上傳,而 file-uploader 也有了改版,有時間在找機會寫一下這個新版的 file-uploader,在 ASP.NET MVC 我們使用 file-uploader 可以完成 Ajax 的檔案上傳功能,但是要做的設定以及所需要了解的東西不算少,所以一些前端技術不是很熟練的朋友就會有些障礙,而能夠完成 Ajax 檔案上傳的也不是只有 file-uploader 還有很多前端套件可以替代,但是找來找去有很多都是會使用 flash 技術來完成,我對 flash 並沒有什麼成見,只是能不用就不用,而這一篇就來介紹使用 jQuery Form Plugin 這個前端套件來完成檔案上傳的功能。


jQuery Form Plugin

http://malsup.com/jquery/form/

github Repository
https://github.com/malsup/form/

image

套件介紹、API 使用說明以及範例等等,我就不再多說,可以請各位自行查閱,因為這一篇是說明怎麼用這個套件來完成檔案上傳,以下為此套件有關檔案上傳的 Demo 範例連結,

http://malsup.com/jquery/form/#file-upload

 

實作

1. 加入 jquery.form.js

從 jQuery Form Plugin 的 github Repository 裡下載最新的檔案,並且將 jquery.form.js 加入到 ASP.NET MVC 專案中,

image

再來就是把 jquery.form.js 給加入到 _layout.cshtml 內,或是也可以加入 App_Start/BundleConfig.cs 當中,

image

 

2. 建立 File Upload Action 與 View

Action

image

public ActionResult Upload()
{
    return View();
}
 
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
    if (file != null)
    {
        if (file.ContentLength > 0)
        {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(Server.MapPath("~/FileUploads"), fileName);
            file.SaveAs(path);
        }
    }
    return RedirectToAction("Upload");
}
View

image

@{
    ViewBag.Title = "Upload";
}
 
<h2>Upload</h2>
<hr />
 
<form id="UploadForm" action="@Url.Action("Upload")" method="post" enctype="multipart/form-data">  
  <label for="file">Filename:</label>
  <input type="file" name="file" id="file" />
  <input type="submit" />
</form>

 

3. 加入前端 Javascript Alert:toastr

上傳檔案成功或是失敗都必須要顯示訊息,可以在頁面中找個地方顯示訊息,不過這邊我是希望以 Alert 的方式來左顯示,所使用的 Javascript Notoification 套件為「toastr」,會使用它的原因在於「簡單」而且可以提供四種基本訊息顯示樣式:Success, Info, Warning, Error,並且可以設定顯示位置以及顯示的動態效果,

Demo:http://codeseven.github.com/toastr/

Download:https://github.com/CodeSeven/toastr

image

會用它更重要的一點是,toastr 可以從 NuGet 裡下載,

image

從 Nuget 裡將 toastr 加入到專案裡,會自動將 css 檔案加入到 Content 目錄、js 檔案加入到 Scripts 目錄裡,

image

image

也手動把 toastr 的 css 與 js 給加入到 _Layout.cshtml 裡,

image

image

使用方式:

// Display a info toast
toastr.info('Display a info toast')
 
// Display a warning toast
toastr.warning('Display a warning toast')
 
// Display a success toast, with a title
toastr.success('Display a success toast', 'Success Message')
 
// Display an error toast, with a title
toastr.error('Display an error toast.', 'Error Message')

另外 toastr 是 Responsive 的,看看以下的測試結果,
http://goo.gl/Ijccm

 

4. 修改後端程式並在 View 加入  Javascript 程式

後端 Controller 的 Action 程式修改如下,回傳 JSON 資料讓前端的 toastr 顯示處理訊息,

public ActionResult Upload()
{
    return View();
}
 
[HttpPost]
public JsonResult Upload(HttpPostedFileBase file)
{
    Dictionary<string, object> jo = new Dictionary<string, object>();
 
    if (file == null)
    {
        jo.Add("success", false);
        jo.Add("message", "file upload error.");            
    }
    else
    {
        if (file.ContentLength > 0 && file.ContentLength < (1 * 1024 * 1024))
        {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(Server.MapPath("~/FileUploads"), fileName);
            file.SaveAs(path);
 
            jo.Add("success", true);
            jo.Add("message", file.FileName);
            jo.Add("ContentLenght", file.ContentLength);
        }
        else
        {
            if (file.ContentLength <= 0)
            {
                jo.Add("success", false);
                jo.Add("message", "請上傳正確的檔案.");
            }
            else if(file.ContentLength > (1 * 1024 * 1024))
            {
                jo.Add("success", false);
                jo.Add("message", "上傳檔案大小不可超過 1MB.");
            }
        }
    }
    return Json(jo);
}

前端 Javascript 程式如下:

<script type="text/javascript">
    $(function () {
 
        $("#UploadForm").ajaxForm({
            iframe: true,
            dataType: "json",
            success: function (result) {
                $("#UploadForm").resetForm();
                if (result.success) {
                    toastr.success(result.message, 'Success Message')
                }
                else {
                    toastr.error(result.message, 'Error Message')
                }
            },
            error: function (xhr, textStatus, errorThrown) {
                $("#UploadForm").resetForm();
                toastr.error('檔案上傳錯誤.', 'Error Message')
            }
        });
    });
</script>

 

測試

上述的前置作業以及前後端程式都完成之後,執行程式進行測試,瀏覽器使用 Firefox 並且開啟 Firebug 來做觀察,

SNAGHTML9be7a8e

成功上傳一個檔案,

SNAGHTML9c33362

觀察前端收到後端傳來的 JSON 訊息,

image

 

我在後端 Action 方法中有加上限制不能上傳超過 1MB 的檔案,所以接下來我上傳一個超過 1MB 的檔案,

SNAGHTML9c55083

觀察前端所接收到的 JSON 訊息,

image

 

故意不選擇檔案就按下 Submit 送出查詢,

SNAGHTML9c7654a

觀察前端所接收到的 JSON 訊息,

image

 


以上就是這一次練習在 ASP.NET MVC 4 網站中使用 jQuery Form Plugin 來完成 Ajax 檔案上傳的功能,上面的都是基本的操作,其實還可以更進階,不過那就留到以後再繼續說明。

 

相關連結:

jQuery Form Plugin
http://malsup.com/jquery/form/

Simple javascript toast notifications - toastr
https://github.com/CodeSeven/toastr
http://codeseven.github.com/toastr/

Simple JavaScript Notifications with toastr | John Papa
http://www.johnpapa.net/toastr100beta/

 

以上

4 則留言:

  1. toastr 好像在IE裡不行 @@

    回覆刪除
    回覆
    1. IE 10 正常的很呀...(不要跟我說 IE 6,7,8

      刪除
    2. IE 9 也很正常的,如果真的有問題,請逕自到 toastr 的 Github 向作者提出 issuse

      刪除
  2. 感謝版主,寫得太好了,淺顯易懂

    回覆刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。