2013年5月1日 星期三

ASP.NET Ajax Control Toolkit - April 2013 Release 更新功能:AjaxFileUpload

最近很多更新,上週是 Enterprise Library 6 的更新發佈,而這一週讓我注意到的是 AJAX Control Toolkit 的更新,這一次的 AJAX Control Toolkit 更新日期為 2013-04-30,改善了兩個的 AJAX 控制項,分別為:AjaxFileUpload 與 MaskedEdit,尤其是 AjaxFileUpload Control,相信這一個功能解決了許多 ASP.NET 開發人員長久以來的問題,雖然說檔案上傳的第三方套件很多,但有些會受限於 jQuery 與 Postback 的整合,大多 ASP.NET 開發人員看到 jQuery 都是先退後三步(或是說 jQuery 不好、影響效能等等之謬論),不過 ASP.NET 官方在 May 2012 Release 之後,讓開發人員可以直接使用官方的 AJAX 上傳檔案控制項,並且可以與原本的 HtmlEditorExtender 做整合。

雖然說我這邊主要關注 ASP.NET MVC 的開發,但畢竟工作上還是得要面對 ASP.NET WebForm,雖然現在已經很少會去用到 Ajax Control Toolkit 的控制項,但是對於 ASP.NET 開發有幫助的控制項是不會放過的。

 


ASP.NET Ajax Control Toolkit - April 2013 Release

http://ajaxcontroltoolkit.codeplex.com/releases/view/105897

image

這一次的更新提供了三種版本,分別提供給使用 .NET Framework 3.5, 4.0, 4.5 的專案使用,所以可以依據各位開發專案所使用的 .NET Framework 版本下載使用,而 AjaxFileUpload 在這三個版本都有提供。

 

加入工具箱

如果 Visual Studio 工具箱要加入 Ajax Control Toolkit 的控制項,就從上面的下載頁面先下載檔案,下載檔案之後先將壓縮檔解開,稍後 Visual Studio 工具箱加入控制項時就會需要用到,然後在工具箱按右鍵並選擇「加入索引標籤」,

image

接著輸入「Ajax Control Toolkit」

image

然後接下來要加入 Ajax Control Toolkit 的控制項,在剛剛建立的 Ajax Control Toolkit 標籤下按右鍵並點選「選擇項目」,

image

第一次開啟「選擇工具箱項目」載入會比較慢,

SNAGHTML2994e7a

點選「選擇工具箱項目」視窗中的「瀏覽」按鍵,

SNAGHTML29a53a8

然後在剛剛下載並解開壓縮檔的目錄位置選擇「AjaxControlToolkit.dll」

image

選擇檔案之後就回到「選擇工具箱項目」的視窗並且載入選取的檔案,

SNAGHTML29f274b

接著當那個「正在載入選取的檔案」完成並且消失後,就可以看到已經有把剛剛加入的 Ajax Control Toolkit 相關項目給反白選取,然後就是按下「確定」按鍵,

SNAGHTML2a10fb6[4]

完成工具箱加入 Ajax Control Toolkit 控制項項目

image

 

專案加入 Ajax Control Toolkit 參考

現在開發專案要使用 Ajax Control Toolkit 也是相當方便,可以由 NuGet 取得並安裝,如下圖:

image

image

 

AjaxFileUpload

這邊先列幾個 AjaxFileUpload 的功能重點:

  • 支援 Ajax 檔案上傳
  • 多檔上傳
  • 上傳進度條顯示(瀏覽器需有支援 HTML5 File API, ex: IE10, Firefox 9 以上, Chrome 17 以上)
  • 拖放檔案上傳(非 IE 瀏覽器可,ex: Firefox, Chrome)
  • 分段上傳(適用於大型檔案上傳使用,但瀏覽器需支援 HTML5 File API)

大家可以先前往 ASP.NET AJAX Control Toolkit Sample Site 的 AjaxFileUpload Sample 看看這個 AjaxFileUpload 控制項的功能。

http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/AjaxFileUpload/AjaxFileUpload.aspx

image

 

實作

接下來我們建立一個新的網站(使用 VS2012, ASP.NET WebForm + .NET Framework 4.5),在網站裡加入一個新網頁然後在網頁上加入 Ajax ScriptManager 與 AjaxFileUpload 控制項,下圖的內容是預設的 AjaxFileUpload 樣式,

image

在 AjaxFileUpload 的事件為 UploadedComplete,對應到後端的事件處理做檔案上傳等工作,

另外還有幾個屬性:

AllowedFileTypes, 可以設定使用者可以上傳檔案的類型,使用副檔名,若要允許多種檔案類別則使用逗號分隔。

MaximumNumberOfFiles, 設定多檔上傳的最大數目。

ChunkSize, 分段上傳大小。

ThrobberID, 當瀏覽器有支援 HTML5 File API 時的上傳會顯示進度條,但是沒有 HTML5 File API 的瀏覽器在上傳檔案時就無法顯示進度條,如果有設定這個 ThrobberID 的話,就可以顯示 ThrobberID 內所設定的控制項內容,通常會是一張圖或是文字。

OnClientUploadComplete, 檔案上傳結束後的前端 Javascript 事件處理,指定 funciton 名稱。

OnClientUploadError, 當檔案上傳發生錯誤時的前端 Javascript 事件處理,指定 funciton 名稱。

 

Web.Config

首先在 system.web 區段增加以下的內容:

<httpHandlers>
    <add verb="*" path="AjaxFileUploadHandler.axd" type="AjaxControlToolkit.AjaxFileUploadHandler, AjaxControlToolkit"/>
</httpHandlers>

再來就是增加 system.webServer 區段內容:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <handlers>
        <add name="AjaxFileUploadHandler" verb="*" path="AjaxFileUploadHandler.axd" type="AjaxControlToolkit.AjaxFileUploadHandler, AjaxControlToolkit"/>
    </handlers>
    <security>
        <requestFiltering>
            <requestLimits maxAllowedContentLength="4294967295"/>
        </requestFiltering>
    </security>
</system.webServer>

ASPX 設定

先在頁面上加入 Ajax Control Toolkit 的「ToolkitScriptManager」,

image

然後加入 AjaxFileUpload 控制項與其他會使用到的控制項,並且設定好屬性與事件,

image

Code Behind

在後端程式加入以下的程式內容,

string[] contentTypes = new string[] { ".jpg", ".jpeg", ".png", ".bmp", ".gif" };
 
protected void AjaxFileUpload1_UploadComplete(object sender, AjaxFileUploadEventArgs file)
{
    if (this.contentTypes.Contains(file.ContentType))
    {
        if (file.FileSize <= 1024 * 1024 * 4)
        {
            string filePath = string.Concat("~/FileUploads/", file.FileName);
            this.AjaxFileUpload1.SaveAs(MapPath(filePath));
        }
        else
        {
            file.PostedUrl = "Images/fileTooBig.gif";
        }
    }
}

 

完成上面的設定與輸入完程式內容之後就大致完成了,當然也需要建立上傳檔案的目錄,所以就可以執行看看,然而執行之後的畫面竟然不是我們在 SampleSite 所看到的樣子,甚至於還有錯誤訊息顯示,

image

這是因為改用 AjaxControlToolkit 的 ToolkitScriptManager 之後,原本網站中的參考「Microsoft.ScriptManager.MsAjax.dll」導致這個錯誤的發生,這個在去年的「September 2012 Release of the Ajax Control Toolkit」的更新中重點,比較詳細的內容在 Stephen Walther 的部落格有一篇文章有詳細說明「September 2012 Release of the Ajax Control Toolkit」。

我們可以從網站專案的「bin」目錄裡把「Microsoft.ScriptManager.MsAjax.dll」移除,以解決這個問題,移除之後再重新整理網頁就可以看到 AjaxFileUpload 應該有的樣子並且不會出現錯誤訊息,

image

讓我們上傳幾個檔案試試看,先選擇幾個要上傳的檔案,

image

然後按下「Upload」之後就可以看到上傳進度的顯示,已經完成上傳的檔案以綠色標示,上傳中以橘色標示,尚未上傳以藍色標示,

image

檔案上傳完成

image

上傳完成後回應給前端的是 JSON 內容,

image

image

 

基本的功能就大概如此,如果想要做到更進階一點的功能,例如 SampleSite -AjaxFileUpload 所呈現的上傳後顯示預覽圖的功能,可以從 CodePlex - Ajax Control Toolkit 下載檔案,檔案裡有「AjaxControlToolkitSampleSite.zip」壓縮檔,這裡面包含 SampleSite 裡的所有 Ajax Control Toolkit 控制項的範例程式,大家可以從裡面看看 SampleSite 所呈現的功能與效果是怎麼做的。

SNAGHTML3cdd04d

 

補充更新:

1. 上傳失敗時

如果要呈現上傳失敗的內容,雖然不能修改 StatusMessages(唯讀屬性),但可從 PostedUrl 內容來加以判斷,下圖是我參考 SampleSite 內的程式碼,將 ASPX 頁面做了修改,可以顯示上傳後的圖片,當上傳檔案超過時就會回傳 file too big 的圖片,

image

2. AjaxFileUpload 在去年就已經發佈了

其實 AjaxFileUpload 這個控制項並不是這一次的更新才新增的功能,在 May 2012 Release 時就可以加入了,我們可以在 Stephen Walter 所寫的「Ajax Control Toolkit May 2012 Release」這篇文章裡的了解更多內容,在該篇文章裡也同時介紹了 AjaxFileUpload 與 HtmlEditorExtender 的整合。

3. 大型檔案的分段上傳

上傳大型檔案的分段上傳處理,畫面如下(上傳的 MP4 影片是去年的 ASP.NET Fall 2012 Update Preview):

image

每個分段的大小就是我們事先所設定的 ChunkSize,如果頁面上 AjaxFileUpload 的 ChunkSize 屬性沒有設定的話,將會使用預設的檔案上傳 maxRequestLength (The default is 4096 KB (4 MB)),

image

4. 目前還沒有直接的方式去修改 AjaxFileUpload 介面上的顯示文字

image

image

上面兩張圖用紅線框起來的文字,目前並沒有直接的方式可以去修改,所以目前都只能顯示英文,可能有人會想說應該可以在前端用 jQuery 的方式對文字做替換的動作,我必須說 …… 不要花這個時間去做這些事,只會徒勞無功而已。

 


參考連結:

AJAX Control Toolkit @ CodePlex

ASP.NET Ajax Control Toolkit - April 2013 Release Downloads

April 2013 Release of the Ajax Control Toolkit | Stephen Walther

September 2012 Release of the Ajax Control Toolkit | Stephen Walther

Ajax Control Toolkit May 2012 Release | Stephen Walther

 

以上

17 則留言:

  1. 很棒的文章!!

    "完成上面的設定與輸入玩程式內容之後就大致完成了"
    有錯字唷XDD

    回覆刪除
    回覆
    1. 感謝你的告知,錯字已經修正了。

      刪除
  2. 我用此版本會遇到上傳檔案後無法開啟的狀況,如doc、xls 或某些圖片等檔案,但上傳壓縮檔或文字但和某些圖片卻又可以開啟,
    使用先前的版本不會有這個問題,這個版本才會,請問版主有遇到這個問題嗎?

    回覆刪除
    回覆
    1. 的確,我在做測試的時候並沒有使用 doc, docx, xls, xlsx 等 office 檔案來做上傳測試,看到你的回應之後再去做測試,會出現檔案損毀的訊息,但都還可以開啟,不過有的檔案會出現亂碼以及文件內容的格式亂掉(我是用 office 2013),而在 AjaxControlToolkit.codeplex.com 已經有人反應這個問題了(不曉得是不是你所建立的 Issus ?),我們就密切觀察這個 issue 的後續回應吧。
      https://ajaxcontroltoolkit.codeplex.com/workitem/27418

      刪除
    2. 謝謝版主測試,那邊是我去反應的問題。

      刪除
    3. 中文檔名的話有很大機率上傳之後檔案會毀損,開不起來。研究之後發現主要原因是AjaxFileUpload的套件有bug, 在某一版之前AjaxFileUpload.SaveAs()是直接把檔案傳到指定位置, 但在某一版之後SaveAs()方法會先把檔案存到使用者temp資料夾下的一個亂數資料夾, 再"移"到使用者指定要儲存檔案的地方。為何會這樣改我不清楚,可能是為了加入可上傳至微軟的Azure空間有關係,SaveAs的code可用ildasm反組譯後再編譯成C# code就可清楚看到。不過SaveAs()方法改成此方式之後,對於中文檔名的檔案(EX.我的文件.doc)在上傳完成後會遺留"一些"MIME type的"字串",為什麼說一些呢,例如檔案是doc的話,MIME類型完整字串是"application/msword",實際上遺留在檔案最前面幾個byte的字串可能是"word\r\n",實際遺留的字串長度會根據上傳檔案的類型有所不同。為什麼我會發現呢?其實只要上傳一個.txt格式的文字文件,在打開之後就會看到文字文件內遺留了"text/plain"這個字串後面的幾個字(EX: /plain)。就因為這"一些"遺留的字串導致上傳後檔案損毀,因為前面幾個byte有"遺留"的字串,所以開不起來。經測試之後全英文檔名的檔案不會發生這種問題。我的解決方法就是找出這些遺留的字串,去掉,重新存檔,如此一來就可以得到和上傳的時候一樣的檔案了。以下是我寫的code,若有需要的人可參考使用:

      刪除
    4. 因不能直接貼code,所以我把他寫道word文件中,需要的人請自行下載吧
      https://mega.co.nz/#!EwwWSCoa!Yw85GhOcLiKu2W54WMMEUFZaQtl72Rcz_i-2x8clk6s

      刪除
    5. 請問有人可以再分享 中文檔名 會造成檔案損毀的BUG解決方法嗎?
      上面大大的載點已經失效了。

      刪除
    6. 新版的ajax已經解決這個問題,有人有問題的話可以去更新!!!

      刪除
  3. 版主您好~

    想請教,Ajax Control Toolkit這個擴充套件

    公司的網站可以直接使用嗎?(有買Visual Studio 2010了)

    回覆刪除
    回覆
    1. 可以呀,不過要注意版本,
      VS2010 不能使用 .NET 4.5 的版本,看你所開發專案所使用的 .NET 版本,VS2010 可以使用 Ajax Control Toolkit .NET 4

      刪除
    2. 非常感謝版主的回應~

      因為幫朋友公司做網站,怕給他們惹來麻煩~ 所以還是問問再做~

      版本問題小弟會注意的~

      再次感謝~!!

      刪除
  4. 版主您好,
    我用了HtmlEditorExtender套件後,有幾個問題,想請教一下。
    1.要怎樣才可以在Insert Image之後關掉FileUpload視窗?
    2.可以自訂另一個InsertImage按鈕嗎?要怎麼做?
    謝謝。

    回覆刪除
    回覆
    1. HtmlEditorExtender? 這邊討論的應該是 AjaxFileUpload 吧!
      有關你所提出的兩個問題,第一個問題,應該可以把 AjaxFileUpload 放在 Panel 當中,上傳完畢後再去將 Panel 的 Visible 給設定為 False, 而第二個問題, 這就沒有研究過,你可以前往 AjaxControlToolKit 位於 CodePlex 的 Issues 去提問或是找尋相關的問題。
      https://ajaxcontroltoolkit.codeplex.com/workitem/list/basic

      刪除
  5. 作者已經移除這則留言。

    回覆刪除

提醒

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

最近的留言