ASP.NET MVC中使用Dropzone.js實現圖片的批量拖拽上傳


說在前面

  最近在做一個MVC相冊的網站(這里),需要批量上傳照片功能,所以就在網上搜相關的插件,偶然機會發現Dropzone.js,試用了一下完全符合我的要求,而且樣式挺滿意的,於是就在我的項目中使用了這個插件。在使用的過程中發現中文的相關文檔較少,說多了都是淚,硬着頭皮看官方的網站,本來英文不咋地,只能邊查單詞邊用了,於是就有了這篇文章,主要是總結在使用Dropzone中的遇到的一些問題及詳細的使用步驟。

Dropzone.js是啥?

  Dropzone.js是一個開源庫,提供拖放文件上傳及圖像預覽。它是輕量級的,不依賴於任何其他庫(如jQuery),並且是高度可定制的,官網在這里。首先說在前面的是因為這是一個基於Html APIs的插件,所以有下列瀏覽器支持:

  • Chrome 7+
  • Firefox 4+
  • IE 10+
  • Opera 12+ (Version 12 for MacOS is disabled because their API is buggy)
  • Safari 6+

  注意:如果您的客戶還在使用IE10以下的瀏覽器,那可能這篇文章不太適合您,或者您可以說服客戶放棄使用IE,可能獲得不一樣的體驗。

效果圖

  直接上幾張效果圖,大家先看看是否符合您的要求,再決定是否使用。

  

  

  

如何下載?

  官網提供的js下載,在這里,這僅僅是一個js,不包括相關的樣式、圖片等,所以建議從Github上下載完整的包,地址在這里。下載這個項目最簡單的方法是使用右側的Download ZIP,會自動將所有文件打包成zip格式的文件下載下來,里面的downloads文件夾就是我們需要的,包括需要用到的js、圖片、css等文件。

如何使用?

  dropzone官網提供了Demo,但是Demo中沒有實現一次上傳多張圖片的功能,而且也沒有提供服務器端C#的相關代碼。所以我就把使用的步驟總結了一下,方便以后的復用。在這里我把使用方法分為前端和后端的代碼,前端主要是文件的引用、dropzone初始化、以及相關的屬性事件說明。后端就是指MVC中Action了,主要功能是從Request獲取文件,存放到服務器中。下面讓我細細道來。

前端

   1、引用文件

  首先呢,肯定是先把下載的文件分類放到自己的項目中,這樣便於以后的管理,也符合國際慣例。

  然后就需要在頁面中引用,引用的代碼如下:

//樣式文件
<link href="~/Content/css/dropzone.css" rel="stylesheet" />

//jQuery文件,不是必需的
<script src="~/Scripts/jquery-1.8.2.min.js"></script>

//js文件
<script src="~/Scripts/dropzone.js"></script>

  大家看到我引用了三個文件,其中jQuery的文件不是必需的,因為在文章開頭也介紹過dropzone是獨立的庫,不需要依賴jQuery,我為了操作方便,所以在這里引用了一下,看個人選擇了。

  2、建立表單元素  

<!--class="dropzone" 使用dropzone自帶的樣式 樣式在引用的CSS中-->
<form action="/"
    class="dropzone"
    enctype="multipart/form-data"
    id="my-dropzone"
    method="post">
    <!--上傳圖片時,需要同時提交的數據,這里做個演示-->
    @Html.Hidden("hidAlbumId")
</form>
<div>
    <!--上傳按鈕,提供多張圖片一次性上傳的功能-->
    <button type="submit" id="submit-all" disabled="disabled">上傳</button>
</div>

  3、初始化Dropzone,並添加屬性和事件

<script>
        //Dropzone的初始化,myDropzone為form的id
        Dropzone.options.myDropzone = {

            //指定上傳圖片的路徑
            url: "@Url.Action("BatchUpload", "PhotoUpload")",

            //添加上傳取消和刪除預覽圖片的鏈接,默認不添加
            addRemoveLinks: true,

            //關閉自動上傳功能,默認會true會自動上傳
            //也就是添加一張圖片向服務器發送一次請求
            autoProcessQueue: false,

            //允許上傳多個照片
            uploadMultiple: true,

            //每次上傳的最多文件數,經測試默認為2,坑啊
            //記得修改web.config 限制上傳文件大小的節
            parallelUploads: 100,

            init: function () {
                var submitButton = document.querySelector("#submit-all")
                myDropzone = this; // closure

                //為上傳按鈕添加點擊事件
                submitButton.addEventListener("click", function () {
                    //手動上傳所有圖片
                    myDropzone.processQueue();
                });

                //當添加圖片后的事件,上傳按鈕恢復可用
                this.on("addedfile", function () {
                    $("#submit-all").removeAttr("disabled");
                });

                //當上傳完成后的事件,接受的數據為JSON格式
                this.on("complete", function (data) {
                    if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) {
                        var res = eval('(' + data.xhr.responseText + ')');
                        var msg;
                        if (res.Result) {
                            msg = "恭喜,已成功上傳" + res.Count + "張照片!";
                        }
                        else {
                            msg = "上傳失敗,失敗的原因是:" + res.Message;
                        }
                        $("#message").text(msg);
                        $("#dialog").dialog("open");
                    }
                });

                //刪除圖片的事件,當上傳的圖片為空時,使上傳按鈕不可用狀態
                this.on("removedfile", function () {
                    if (this.getAcceptedFiles().length === 0) {
                        $("#submit-all").attr("disabled", true);
                    }
                });
            }
        };
</script>

  這樣前端的工作基本完成了,下面來看看后端的工作。

★后端

   后端的功能挺簡單,就是接收文件,然后將數據保存到服務器上,並返回JSON數據。代碼如下:

[HttpPost]
public ActionResult BatchUpload()
{
    bool isSavedSuccessfully = true;
    int count = 0;
    string msg = "";

    string fileName = "";
    string fileExtension = "";
    string filePath = "";
    string fileNewName = "";

    //這里是獲取隱藏域中的數據
    //int albumId = string.IsNullOrEmpty(Request.Params["hidAlbumId"]) ?
    //    0 : int.Parse(Request.Params["hidAlbumId"]);

    try
    {
        string directoryPath = Server.MapPath("~/Content/photos");
        if (!Directory.Exists(directoryPath))
            Directory.CreateDirectory(directoryPath);

        foreach (string f in Request.Files)
        {
            HttpPostedFileBase file = Request.Files[f];

            if (file != null && file.ContentLength > 0)
            {
                fileName = file.FileName;
                fileExtension = Path.GetExtension(fileName);
                fileNewName = Guid.NewGuid().ToString() + fileExtension;
                filePath = Path.Combine(directoryPath, fileNewName);
                file.SaveAs(filePath);

                count++;
            }
        }
    }
    catch (Exception ex)
    {
        msg = ex.Message;
        isSavedSuccessfully = false;
    }

    return Json(new
    {
        Result = isSavedSuccessfully,
        Count = count,
        Message = msg
    });
}

總結

  通過這次實踐,剛發現Html APIs的強大,Dropzone就是通過調用APIs實現的功能,現在自己的技術從各個方面來說已經落后很多了,以后得抓緊自己的業余時間,多做些個人項目,才能在實踐中不斷提高。由於自己對相關技術理解不深,文中必有疏漏,還請大家批評指正。

參考

  http://www.dropzonejs.com/

  http://www.dropzonejs.com/bootstrap.html

  http://stackoverflow.com/questions/18059128/dropzone-js-uploads-only-two-files-when-autoprocessqueue-set-to-false

  http://stackoverflow.com/questions/18048825/how-to-limit-the-number-of-dropzone-js-files-uploaded

  http://venkatbaggu.com/file-upload-in-asp-net-mvc-using-dropzone-js-and-html5/

  http://stackoverflow.com/questions/16050965/using-dropzone-js-in-asp-net

  https://github.com/enyo/dropzone/wiki/Upload-all-files-with-a-button


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM