I’m happy to announce the May 2012 release of the Ajax Control Toolkit. This newest release of the Ajax Control Toolkit includes a new file upload control which displays file upload progress. We’ve also added several significant enhancements to the existing HtmlEditorExtender control such as support for uploading images and Source View.
You can download and start using the newest version of the Ajax Control Toolkit by entering the following command in the Library Package Manager console in Visual Studio:
Install-Package AjaxControlToolkit
Alternatively, you can download the latest version of the Ajax Control Toolkit from CodePlex:
http://AjaxControlToolkit.CodePlex.com
The New Ajax File Upload Control
The most requested new feature for the Ajax Control Toolkit (according to the CodePlex Issue Tracker) has been support for file upload with progress. We worked hard over the last few months to create an entirely new file upload control which displays upload progress.
Here is a sample which illustrates how you can use the new AjaxFileUpload control:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="01_FileUpload.aspx.cs" Inherits="WebApplication1._01_FileUpload" %> <html> <head runat="server"> <title>Simple File Upload</title> </head> <body> <form id="form1" runat="server"> <div> <ajaxToolkit:ToolkitScriptManager runat="server" /> <ajaxToolkit:AjaxFileUpload id="ajaxUpload1" OnUploadComplete="ajaxUpload1_OnUploadComplete" runat="server" /> </div> </form> </body> </html>
The page above includes a ToolkitScriptManager control. This control is required to use any of the controls in the Ajax Control Toolkit because this control is responsible for loading all of the scripts required by a control.
The page also contains an AjaxFileUpload control. The UploadComplete event is handled in the code-behind for the page:
namespace WebApplication1 { public partial class _01_FileUpload : System.Web.UI.Page { protected void ajaxUpload1_OnUploadComplete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e) { // Generate file path string filePath = "~/Images/" + e.FileName; // Save upload file to the file system ajaxUpload1.SaveAs(MapPath(filePath)); } } }
The UploadComplete handler saves each uploaded file by calling the AjaxFileUpload control’s SaveAs() method with a full file path.
Here’s a video which illustrates the process of uploading a file:
Warning: in order to write to the Images folder on a production IIS server, you need Write permissions on the Images folder. You need to provide permissions for the IIS Application Pool account to write to the Images folder. To learn more, see:
http://learn.iis.net/page.aspx/624/application-pool-identities/
Showing File Upload Progress
The new AjaxFileUpload control takes advantage of HTML5 upload progress events (described in the XMLHttpRequest Level 2 standard). This standard is supported by Firefox 8+, Chrome 16+, Safari 5+, and Internet Explorer 10+. In other words, the standard is supported by the most recent versions of all browsers except for Internet Explorer which will support the standard with the release of Internet Explorer 10.
The AjaxFileUpload control works with all browsers, even browsers which do not support the new XMLHttpRequest Level 2 standard. If you use the AjaxFileUpload control with a downlevel browser – such as Internet Explorer 9 — then you get a simple throbber image during a file upload instead of a progress indicator.
Here’s how you specify a throbber image when declaring the AjaxFileUpload control:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="02_FileUpload.aspx.cs" Inherits="WebApplication1._02_FileUpload" %> <html> <head id="Head1" runat="server"> <title>File Upload with Throbber</title> </head> <body> <form id="form1" runat="server"> <div> <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" /> <ajaxToolkit:AjaxFileUpload id="ajaxUpload1" OnUploadComplete="ajaxUpload1_OnUploadComplete" ThrobberID="MyThrobber" runat="server" /> <asp:Image id="MyThrobber" ImageUrl="ajax-loader.gif" Style="display:None" runat="server" /> </div> </form> </body> </html>
Notice that the page above includes an image with the Id MyThrobber. This image is displayed while files are being uploaded.
I use the website http://AjaxLoad.info to generate animated busy wait images.
Drag-And-Drop File Upload
If you are using an uplevel browser then you can drag-and-drop the files which you want to upload onto the AjaxFileUpload control. The following video illustrates how drag-and-drop works:
Remember that drag-and-drop will not work on Internet Explorer 9 or older.
Accepting Multiple Files
By default, the AjaxFileUpload control enables you to upload multiple files at a time. When you open the file dialog, use the CTRL or SHIFT key to select multiple files.
If you want to restrict the number of files that can be uploaded then use the MaximumNumberOfFiles property like this:
<ajaxToolkit:AjaxFileUpload id="ajaxUpload1" OnUploadComplete="ajaxUpload1_OnUploadComplete" ThrobberID="throbber" MaximumNumberOfFiles="1" runat="server" />
In the code above, the maximum number of files which can be uploaded is restricted to a single file.
Restricting Uploaded File Types
You might want to allow only certain types of files to be uploaded. For example, you might want to accept only image uploads. In that case, you can use the AllowedFileTypes property to provide a list of allowed file types like this:
<ajaxToolkit:AjaxFileUpload id="ajaxUpload1" OnUploadComplete="ajaxUpload1_OnUploadComplete" ThrobberID="throbber" AllowedFileTypes="jpg,jpeg,gif,png" runat="server" />
The code above prevents any files except jpeg, gif, and png files from being uploaded.
Enhancements to the HTMLEditorExtender
Over the past months, we spent a considerable amount of time making bug fixes and feature enhancements to the existing HtmlEditorExtender control. I want to focus on two of the most significant enhancements that we made to the control: support for Source View and support for uploading images.
Adding Source View Support to the HtmlEditorExtender
When you click the Source View tag, the HtmlEditorExtender changes modes and displays the HTML source of the contents contained in the TextBox being extended. You can use Source View to make fine-grain changes to HTML before submitting the HTML to the server.
For reasons of backwards compatibility, the Source View tab is disabled by default. To enable Source View, you need to declare your HtmlEditorExtender with the DisplaySourceTab property like this:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="05_SourceView.aspx.cs" Inherits="WebApplication1._05_SourceView" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head id="Head1" runat="server"> <title>HtmlEditorExtender with Source View</title> </head> <body> <form id="form1" runat="server"> <div> <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server" /> <asp:TextBox id="txtComments" TextMode="MultiLine" Columns="60" Rows="10" Runat="server" /> <ajaxToolkit:HtmlEditorExtender id="HEE1" TargetControlID="txtComments" DisplaySourceTab="true" runat="server" /> </div> </form> </body> </html>
The page above includes a ToolkitScriptManager, TextBox, and HtmlEditorExtender control. The HtmlEditorExtender extends the TextBox so that it supports rich text editing.
Notice that the HtmlEditorExtender includes a DisplaySourceTab property. This property causes a button to appear at the bottom of the HtmlEditorExtender which enables you to switch to Source View:
Note: when using the HtmlEditorExtender, we recommend that you set the DOCTYPE for the document. Otherwise, you can encounter weird formatting issues.
Accepting Image Uploads
We also enhanced the HtmlEditorExtender to support image uploads (another very highly requested feature at CodePlex). The following video illustrates the experience of adding an image to the editor:
Once again, for backwards compatibility reasons, support for image uploads is disabled by default. Here’s how you can declare the HtmlEditorExtender so that it supports image uploads:
<ajaxToolkit:HtmlEditorExtender id="MyHtmlEditorExtender" TargetControlID="txtComments" OnImageUploadComplete="MyHtmlEditorExtender_ImageUploadComplete" DisplaySourceTab="true" runat="server" > <Toolbar> <ajaxToolkit:Bold /> <ajaxToolkit:Italic /> <ajaxToolkit:Underline /> <ajaxToolkit:InsertImage /> </Toolbar> </ajaxToolkit:HtmlEditorExtender>
There are two things that you should notice about the code above. First, notice that an InsertImage toolbar button is added to the HtmlEditorExtender toolbar. This HtmlEditorExtender will render toolbar buttons for bold, italic, underline, and insert image.
Second, notice that the HtmlEditorExtender includes an event handler for the ImageUploadComplete event. The code for this event handler is below:
using System.Web.UI; using AjaxControlToolkit; namespace WebApplication1 { public partial class _06_ImageUpload : System.Web.UI.Page { protected void MyHtmlEditorExtender_ImageUploadComplete(object sender, AjaxFileUploadEventArgs e) { // Generate file path string filePath = "~/Images/" + e.FileName; // Save uploaded file to the file system var ajaxFileUpload = (AjaxFileUpload)sender; ajaxFileUpload.SaveAs(MapPath(filePath)); // Update client with saved image path e.PostedUrl = Page.ResolveUrl(filePath); } } }
Within the ImageUploadComplete event handler, you need to do two things:
1) Save the uploaded image (for example, to the file system, a database, or Azure storage)
2) Provide the URL to the saved image so the image can be displayed within the HtmlEditorExtender
In the code above, the uploaded image is saved to the ~/Images folder. The path of the saved image is returned to the client by setting the AjaxFileUploadEventArgs PostedUrl property.
Not surprisingly, under the covers, the HtmlEditorExtender uses the AjaxFileUpload. You can get a direct reference to the AjaxFileUpload control used by an HtmlEditorExtender by using the following code:
void Page_Load() { var ajaxFileUpload = MyHtmlEditorExtender.AjaxFileUpload; ajaxFileUpload.AllowedFileTypes = "jpg,jpeg"; }
The code above illustrates how you can restrict the types of images that can be uploaded to the HtmlEditorExtender. This code prevents anything but jpeg images from being uploaded.
Summary
This was the most difficult release of the Ajax Control Toolkit to date. We iterated through several designs for the AjaxFileUpload control – with each iteration, the goal was to make the AjaxFileUpload control easier for developers to use. My hope is that we were able to create a control which Web Forms developers will find very intuitive.
I want to thank the developers on the Superexpert.com team for their hard work on this release.
I sure hope this works like demonstrated. If so, the ajaxfileuploader will save my project, since the form has need of five(5) muliple fileuploaders. I did not want to limit my users to just one file per asyncfileupload browse click. However, the 3-4 mouse clicks per file to upload more that one was too tedious for most users. I have just downloaded and installed the 5/2012 stable version 4.1.5116.0 but cannot find what you are describing as “AjaxFileUpload” when reloading the Ajax Control Toolkit.
The best release of Ajax Control Toolkit in years!
Can you give more details on how the uploader control communicates with the server. It seems like the file is posted to te page’s URL and the whole page lifecycle will run. Is there support for providing a handler to accept the file or any other options regarding communication with the server.
@Stilgar, That’s correct — the AjaxFileUpload control does not use a handler, it posts back to the same page. We wanted to make it super easy for Web Forms developers to use the control. In order to handle the posted file, you simply write a handler for the Ajax File Upload UploadComplete event.
We did add a property named AjaxFileUpload.IsInFileUploadPostback so that you could avoid running code when a page is created in response to processing a file postback. Otherwise, like the UpdatePanel, the AjaxFileUpload executes the entire page lifecycle when you post a file.
Okay, AjaxControlToolkit.4.1.60501 Has been loaded and reloaded.
Still no “ajaxfileUpload” control shows up in the toolbox before or after choosing items. The only item with “fileupload” is the asyncfileupload control. Is there another newer version?
@Wendi — The 4.1.60501 version of the correct version (6th year, May 01). Are you sure that you updated the reference to the Ajax Control Toolkit assembly in your Visual Studio project? I just tested on my machine (using both the 3.5/4.0 versions of the Ajax Control Toolkit) and the new AjaxFileUpload control is appearing correctly in my toolbox (with a little icon of a gear).
You might want to try opening the bin folder for your project, delete the AjaxControlToolkit.dll assembly, and then add the reference to the AjaxControlToolkit.dll again.
Great work Stephen. Really like the new FileUpload control. Something I noticed, and I may be overlooking a configuration, is that if I do a Server.Transfer form another page to the page that contains the AjaxFileUpload control, it doesn’t work. If I make the page containing the FileUpload control the start page, it works beautifully. I suspect it has something to do with the URL not changing in the Transfer. Is there a way to compensate for that? Thanks for all your efforts.
@Alex — We did not test for the scenario of doing a server.transfer — I’m sure that you are right, it breaks the postback URL for the Ajax File Upload. Can you please submit a bug for this at http://ajaxcontroltoolkit.codeplex.com/workitem/list/basic
Hi Stephen, finally I was able to gt the proper version of the ajax toolkit to load all of the controls.
Does this version have a particular version of the .net framework , or browser version or anything like that to display and run properly. I made a test project copied your code translated into VB.
One project displays a double asyncfileupload control, the other only display the the select part of the ajaxfileupload as screen shot on your blog. (i.e. the drag an drop part). The crtl/shift key does not select multiple files; such that I can creat the filelist of three files as long as I click the select file button, as pending, the click the upload and it seems to work.
Thank you for your response. I have been trying to find/create a workable solution to the multiple file upload for several months now. I am very excited about this new control. I believe I need to play with it a little more, and maybe I can get it to do what I want it to.
@Wendi — Glad you got it to work. Yes, unfortunately, the design time experience for the Ajax File Upload needs to be improved — right now, the AjaxFileUpload looks like two file uploads widgets. But, this less than ideal design time experience should have no effect on its runtime functionality.
You can only select multiple files using CTRL/SHIFT on browsers that support multiple file uploads — right now, that means every browser except IE9. The IE10 browser will support multiple file uploads.
Hi Stephen, thank you for this awesome piece of work !
When will the sources be available on codeplex?
By the way, http://AjaxLoad.com is not available anymore, the new URL is http://AjaxLoad.info
@Ben — We are working to get all of the source code updated on the CodePlex site by tomorrow. Thanks for the correction on the AjaxLoad.info URL (corrected inline)
Stephen,
Thank you for this information.
Do you have any advice on how best to style the AjaxFileUpload control in the browser?
For example, the default styling uses a mixture of HTML markup, inline styles and a CSS stylesheet loaded via a WebResource.axd. I cannot see a way to: (a) disable the inline styles; (b) configure the fixed markup; (c) disable the CSS stylesheet.
It would seem the only option I have is to try and override the default styles through a custom CSS stylesheet. This is difficult, because the default stylesheet loaded from the WebResource.axd is dynamically appended to the bottom of the HTML head element.
Any help would be appreciated.
Thanks,
Matt
@Matt — Yes, I agree, styling the AjaxFileUpload control could be made easier. Right now, you need to use CSS styles and override its default appearance. Can you please submit a bug for this at http://ajaxcontroltoolkit.codeplex.com/workitem/list/basic
It would be great if you could include some recommendations for how you would like to be able to modify the appearance of the control. For example, if you could suggest some style properties to add to the control.
Is there a change history so we know what bugs have been fixed in other controls since the last release?
Thanks for the Browser info. I guess I will have to wait to use this Cool and badly needed control.
Our Department is currently stuck at IE8 due to other 3rd party apps (for example SAP’s GUI).
P.S. Trying to use the cascadingdropdown control and found out I could not use it at this time either due to the Integer parameter requirement. Oh well back to the drawing board. Thanks.
I’m getting the following error at runtime after following your first couple steps:
“The Controls collection cannot be modified because the control contains code blocks”
AjaxControlToolkit.ScriptObjectBuilder.RegisterCssReferences(Control control) in C:UsersStephenDocumentsReposSuperexpertAjaxControlToolkitServerAjaxControlToolkitExtenderBaseScriptObjectBuilder.cs:328
And by the way, my username is not Stephen, so I don’t even know where that’s caming from.
I should note that I’m using ASP.Net 4.0, and have implemented Routing. Could routing be causing this issue? I see on the CodePlex site that someone has mentioned it’s not working on a page reached by Server.Transfer.
I just tried it without routing, and I still have the same issue…
Stephen,
Great stuff! I just upgraded from the asp.net file upload control to use this ajaxified version. The only issue that I’m having is I’m trying to capture input from a text box upon the UploadComplete event and my text box value always shows up as empty even though it has a value in it. This worked before the conversion and I’ve tried every trick I could think of to get this to work. The only time I can get a value is when I force the page to postback. I’m using an aspx with update panel (with master page) which has an embedded user control in it and I’ve even tried to remove the update panel. The reason I’m trying to capture this input is I want the user to be able to enter a name for the image to be saved to my database instead of a file server. Any help would be appreciated. VS2010, .net Framwork 4.0 C#
Is it just me or is the new AjaxFileUpload control far from finished? (read: buggy)
– The MaximumNumberOfFiles property is ignored on both Firefox en Chrome
– Uploading does not work on IE versions < IE10 (tested with IE9)
Stephen, great to have an update to the HtmlEditorExtender. Will it now handle paste from MS Word?
Thanks again
How do I refresh a GridView/ListView that list all files upon completion of all (or each) file uploads.
Uploading files and displayding success/fail works perfectly.
I tried to bind the GridView.DataBind() in OnUploadComplete event and also add asp:AsyncPostBackTrigger with UploadComplete of the AjaxFileUpload event to the GridView, no luck on either one.
Maybe there is an event that I can use with AjaxFileUpload.IsInFileUploadPostback, so at the end of all uploads, IsInFileUploadPostback will be false and I can do GridView.DataBind() there.
MaximumNumberOfFiles is ignored in Firefox and Chrome.