Tuesday, November 13, 2007

AJAX File Upload

As we all know that if you put any sort of file upload control on a form where you use AJAX (ex. the ASP.NET ScriptManager and UpdatePanel) it won't upload the file via an XMLHttpRequest. So that means you have two options; first not use the update panel; second, put a button on the form that does a full post back to upload the file, and another one to just do the save. Actually the second one could be fairly attractive for providing some sort of feedback on large file uploads, but that isn't the point of this post.

Here's a hack that at least allows me to do this until I can figure out a more elegant approach, but first a quick background. Within my architecture I have web parts which are essentially a tool bar with Save, Cancel & Delete and a form of fields that get updated. I have this wrapped into a nice server side custom control and all my panels use the same architecture so this was a change only in one spot.

Basically what I do is capture the "onchange" event on the <input type="file" id="foo" onchange="swapSaveButtons();" /> control. I then invoke some java script that swaps out the save button on the form that is registered for an async post back (it does this by default on an update panel) for one that does a full post back:

A more elegant approach would be to interact with the ScriptManager with client javascript, but I couldn't find any APIs. So basically in most cases, the normal save button that does the async post back triggers the trip to the server and the AJAX panel is happy. In the case where the user selects a file, we swap out the normal save button with one that does a full post back and the file gets uploaded. Of course this solution isn't perfect, but the worst case scenario is one where there is no file to upload and we still do a round trip. That probably isn't the end of the world.

I would be very happy to hear of other approaches that would be transparent to the user and workflow.