Wow…long time no blogging. As always, busy busy busy… Di tengah kesibukan mengerjakan proyek dadakan di negeri tetangga dengan deadline yang super cepat, nyempatin diri lihat-lihat AJAX Control Toolkit (ACT), siapa tahu ada control baru. Ternyata memang ada. The latest release is Sept 30, 2009. There are two new controls:
- SeaDragon - This version of Seadragon allows you to display an image, and to zoom in and out of that image using mouse button keys without resizing the window.
- AsyncFileUpload - This new control enables you to perform file uploads without doing a postback. The control displays a throbber image during upload and raises client and server events when the upload is complete. This control was contributed by Steven Lindsay.
Let’s focus to AsyncFileUpload. While other open framework and platform have release this kind of control years ago, for example ICEFaces (for JSF) with its <ice:inputFile> control, ACT took quite sometime to release the same control. But, it’s better late than never, isn’t it?
So, let’s try AsyncFileUpload.
1. Download ACT binary here
2. Extract the downloaded zip file. You’ll find among other things are: AjaxControlToolkit.dll and AjaxControlToolkit.pdb
3. Copy those two files to Bin folder of ASP.NET Website project
4. To ease the usage, don’t forget to add these lines in web.config:
<pages>
<controls>
<add namespace="AjaxControlToolkit" assembly="AjaxControlToolkit"
tagPrefix="ajaxToolkit"/>
</controls>
</pages>
5. Now, create a new ASP.NET page (or you can use existing page). Name it whatever you want. Add this tag:
<ajaxToolkit:AsyncFileUpload runat="server" ID="AsyncFileUpload1" Width="400px"
UploaderStyle="Modern" UploadingBackColor="#CCFFFF" />
then right click to the page and View in Browser. You’ll get:
Not bad huh? Change the UploaderStyle to Traditional, you’ll get the old input file.
If you try to click Select File button, browse and select the file, looks like the control will upload the file, but don’t know where the file goes. Why? because you don’t specify the destination yet.
Server-side Event
This control has two server-side events:
- UploadedComplete - Fired on the server side when the file successfully uploaded
- UploadedFileError - Fired on the server side when the uploaded file is corrupted
If the file has been successfully uploaded to server, it’s your responsibility to move/save as to wherever you want. You can use UploadedComplete event to do that.
Change the tag to:
<ajaxToolkit:AsyncFileUpload runat="server" ID="AsyncFileUpload1" Width="400px"
UploaderStyle="Modern" UploadingBackColor="#CCFFFF"
OnUploadedComplete="AsyncFileUpload1_UploadedComplete"/>
Then in aspx code behind, write this event handler:
protected void AsyncFileUpload1_UploadedComplete(object sender,
AjaxControlToolkit.AsyncFileUploadEventArgs e)
{ if (AsyncFileUpload1.HasFile)
{ AsyncFileUpload1.SaveAs(Server.MapPath("~/Uploads/" + Path.GetFileName(e.filename)));
}
}
That code will save as the uploaded file to Upload folder under the root application folder.
By default setting, ASP.NET can handle file upload until 4096 KB (4 MB). You can specify more by change the setting in web.config. Find <system.web> and put something like this <httpRuntime maxRequestLength="102400"/> to allow file upload until 100 MB. Please be aware that change to this setting opens the possibility for denial of service attacks caused by users posting large files to the server. Use it at your own risk.
Client-side Event
To add interactivity, you can handle client-side events. They are:
ClientUploadComplete - the client-side event after the file successfully uploaded
ClientUploadError - the client-side event if the file uploading failed
ClientUploadStarted - the client-side event on the file uploading started
Let’s change the ASPX code to:
1: <script type="text/javascript">
2: function uploadError(sender, args) { 3: $get('labelUploadMsg').innerText = args.get_fileName() + " " + 4: args.get_errorMessage() + " ";
5: $get('labelUploadMsg').style.color = 'red'; 6: }
7:
8: function uploadComplete(sender, args) { 9: var contentType = args.get_contentType();
10: var text = args.get_length() + " bytes";
11: if (contentType.length > 0) { 12: text += ", '" + contentType + "'";
13: }
14:
15: $get('labelUploadMsg').innerText = text; 16: $get('labelUploadMsg').style.color = 'black'; 17: }
18:
19: function uploadStarted(sender, args) { 20: $get('labelUploadMsg').innerText = "Upload is started"; 21: $get('labelUploadMsg').style.color = 'black'; 22: }
23:
24: </script>
1: <ajaxToolkit:AsyncFileUpload OnClientUploadError="uploadError"
2: OnClientUploadComplete="uploadComplete"
3: OnClientUploadStarted="uploadStarted"
4: runat="server" ID="AsyncFileUpload1" Width="400px"
5: UploaderStyle="Modern" UploadingBackColor="#CCFFFF"
6: ThrobberID="activity"
7: OnUploadedComplete="AsyncFileUpload1_UploadedComplete" />
8: <img src="../../App_Global/Images/Skin/activity.gif" runat="server"
9: id="activity" alt="Uploading..."/><br />
10: <div>
11: <span id="labelUploadMsg"></span>
12: </div>
What I do above is:
- Add javascript functions to handle client-side events
- Add throbber image and set ThrobberID. Throbber image is animation image that will be displayed during file upload. You can use any GIF images.
- Add span tag to display messages during upload.
Let’s View In Browser:
If upload is completed successfully:
If it’s failed:
That error is caused by too large file size.
Cool huh?
If you see JS functions that handle client-side events, there’s a parameter called args. It’s an object that has these methods:
- get_fileName()
- get_path()
- get_length()
- get_contentType()
- get_errorMessage()
I’m sure you know what they are used for.
Conclusion
It’s a nice and helpful control. I’ve been waiting for this control years ago. Most of controls/lib (like JQuery uploadify) use Flash to handle async upload, it doesn’t. Don’t expect too much yet. It doesn’t support upload progress (byte by byte) notification yet.
That’s it. Enjoy.