網頁

2012年1月30日 星期一

ASP.NET MVC上傳檔案,使用file-uploader : 基本操作


網站專案大都會使用到上傳檔案的功能,而一般我們大多是直接使用form以及type為file的input element來完成,

例如:

@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { id="FormUpload", enctype = "multipart/form-data" }))
{
    <p>
        Upload File:<input type="file" id="uploadFile" name="uploadFile" size="23" />
        <input type="button" id="ButtonUpload" value="Upload file" />
    </p>
}

這樣的作法是最基本也是最標準的作法,

但是這樣的作法在每次送出檔案上傳到server端後,整個網頁都會Reoload,

於是網路上就有很多AJAX的上傳檔案套件可以讓我們來使用,

而這邊將會以一系列的文章來介紹如何在ASP.NET MVC的環境下使用「file-uploader」這個套件來製作檔案上傳的功能,



valums/file-uploader

 

Ajax Upload; A file upload script with progress-bar, drag-and-drop.

網站:http://valums.com/ajax-upload/

GitHub repository:https://github.com/valums/file-uploader

Download:http://github.com/valums/file-uploader/zipball/master

Wiki:https://github.com/valums/file-uploader/wiki

功能
  • multiple file select, progress-bar in FF, Chrome, Safari
  • drag-and-drop file select in FF, Chrome
  • uploads are cancellable
  • no external dependencies
  • doesn't use Flash
  • fully working with https
  • keyboard support in FF, Chrome, Safari
  • tested in IE7,8; Firefox 3,3.6,4; Safari4,5; Chrome; Opera10.60;

     

    「valums/file-uploader」是個相當容易使用的上傳檔案套件,不需要太繁複設定就可以在套用後就馬上執行功能,

    特色說明:

    1.支援選擇多檔案的上傳(IE, Firefox, Chrome正常而Safari以及Opera無法支援選擇多個檔案)

    image

    2.在Firefox以及Chrome(同屬Webkit的Safari亦同)支援拖曳檔案上傳

    image



    基本使用

    首先從「Download」連結的下載壓縮檔(valums-file-uploader-b3b20b1.zip)

    壓縮檔中的「client」目錄中有以下幾個demo檔案:

    image

    我們要的只有三個檔案:fileuploader.css, fileupload.js, loading.gif,

    將這三個檔案都加入到網站專案中,fileupload.js放到Scripts目錄,其他兩個放到Content目錄中,

    image

     

    前端:View頁面

    在View Page上面放置以下的HTML內容,

    <div id="file-uploader">
        <noscript>
            <p>
                Please enable JavaScript to use file uploader.</p>
            <!-- or put a simple form for upload here -->
        </noscript>
    </div>

    記得頁面上要引用fileupload.css以及fileupload.js

    <link href="@Url.Content("~/Content/fileuploader.css")" rel="stylesheet" type="text/css" />
     
    <script src="@Url.Content("~/Scripts/fileuploader.js")" type="text/javascript"></script>

    接著就是在頁面上使用javascript程式來建立檔案上傳的container element

    <script type="text/javascript" language="javascript">
    <!--
        $(document).ready(function ()
        {
            createUploader();
        });
     
        function createUploader()
        {
            var uploader = new qq.FileUploader(
            {
                element: $('#file-uploader')[0],
                action: '@Url.Action("BasicUpload", "Home")',
            });
        }
    -->
    </script>

    這邊注意到,uploader中的element一定要使用DOM,所以用jQuery selector所選到的元素要轉為DOM node,

    或是說也可以直接用javascript的語法來取得DOM node,

    element: document.getElementById('file-uploader'),

     

    後端:Controller

    傳入BasicUpload方法的參數名稱都是固定使用「qqfile」,

    如果覺得這個名稱不好而想要改的話,就必須連同「fileuploader.js」內也一併做修改,

    所以沒有特殊的需求的話,就還是別去改它。

    後端處理檔案上傳的程式如下:

    public ActionResult BasicUpload(string qqfile)
    
    {
    
        string uploadFolder = "FileUpload";
    
        string path = Server.MapPath(string.Format("~/{0}", uploadFolder));
    
        
    
        try
    
        {
    
            // To handle differences in FireFox/Chrome/Safari/Opera
    
            Stream stream = Request.Files.Count > 0 
    
                ? Request.Files[0].InputStream 
    
                : Request.InputStream;
    
            string filePath = Request.Files.Count > 0
    
                ? Path.Combine(path, System.IO.Path.GetFileName(Request.Files[0].FileName))
    
                : Path.Combine(path, qqfile);
    
            var buffer = new byte[stream.Length];
    
            stream.Read(buffer, 0, buffer.Length);
    
            System.IO.File.WriteAllBytes(filePath, buffer);
    
            return Json(new { success = true }, "text/html");
    
        }
    
        catch (Exception ex)
    
        {
    
            return Json(new { error = ex.Message }, "text/html");
    
        }
    
    }

    因為瀏覽器的不同也讓後端的處理也有所不同(基本上就是分成兩種,一種是IE用而另一個就是非IE),

    IE瀏覽器的上傳,參數「qqfile」是沒有傳入資料的,也取不到「Request.InputStream」,

    而是必須要從「Request.Files[0]」去取得HttpPostedFileBase類別的物件,再從中取得InputStream以及檔案名稱。

    非IE瀏覽器的上傳,可以直接取得「Request.InputStream」並且可以直接取得「qqfile」內容。

    然後再將上傳的位元組陣列寫入到指定目錄路徑的檔案。

     

    而最後不管上傳成功與否,傳回到前端的資料格式雖然是「json」,但是 contentType必須是「text/html」,

    上傳成功:

    {"success":true} 

    上傳失敗:

    {"error":"要顯示的錯誤訊息"} 

     

    如果不是傳回text/html的json資料,IE, Opera瀏覽器是會有以下的情況發生:

    image

    You should return json as a text/html, 
    and escape all '<' as '&lt;', '>' as '&gt;', and '&' as '&amp;'.



    有關於「valums/fi;e-uploader」的基本操作就說明到這裡,而下一篇會再說明進階的使用方式,

    例如:

    • 關閉多選檔案的選項
    • 自定上傳檔案區塊的文字、上傳檔案清單的文字
    • 限制檔案的上傳大小
    • 限制上傳檔案的種類
    • 上傳時也同時上傳其他參數資料
    • 上傳時、上傳完成時的事件處理

    …etc

     

    其他連結:

    Asp.net mvc使用 Ajax Upload上传文件
    http://www.cnblogs.com/bombw/archive/2011/11/02/2232661.html

     

    以上


    沒有留言:

    張貼留言