So, guess who just got the memo ...
Dear Matt,
Uploading large files with ASP.NET is difficult.
Sincerely,
Every ASP.NET Developer and their Mother
After sufficiently embarrassing myself with my earlier post, I decided it was high time I spend a little bit more time understanding this problem. And lo and behold Jon Galloway has already written up a nice survey on the topic. So to bone up on the issues I followed all of the links Jon provided as well the ones provided by all of the one-off emails I received in response to my previous post (thanks everyone).
Of all the upload components I checked-out (SWFUpload, FileUp, Flajaxian FileUploader, RadUpload, NeatUpload, ASP.Net File Upload/Download Module, etc...) I was the most interested in the last 2 (NeatUpload and ASP.Net File Upload/Download Module). They are both free, have my kind of licensing and come with the full source code.
So I downloaded both of these components and played around with plugging them into the demo app I blogged about previously. Both components include progress bar web controls, but I already have a progress bar widget that I really like. So my focus was on seeing what it would take to leverage only the HttpModule portion of these components and checking out how I could have the module interface with my progress bar. Like I mentioned previously, I want something that looks like this ...
NeatUpload Vs. Darren Johnstone's ASP.Net File Upload/Download Module
Both NeatUpload and Darren Johnstone's components seem to have a rather large following, but I chose to see how I could extend Darren's control because it was already using AJAX plus a custom HttpHandler to communication the upload progress back to the client. And that seems really close to what I wanted. If this doesn't pan out, NeatUpload actually seems to have a larger following so I will probably go back and revisit this topic using NeatUpload instead.
How it Works
From what I can tell, Darren's component basically works by injecting a hidden INPUT element into the form that contains the file INPUT(s). The value of the hidden element is a Guid that contains a well-known prefix (Darren uses the token ::DJ_UPLOAD_ID::). Then as his custom HttpModule is processing the request, it looks to see if the form contains this token. If so, he tucks the upload progress information into memory using the id value as the index. Then, if a client wants to query the upload progress, they can query his component using this guid as the look-up value.
Below is a screen capture of the request body. The hidden field is highlighted in yellow.
Querying the Upload Status
The second cool thing about Darren's control is that he has included a custom handler for accessing the progress of an upload. This makes is pretty simple to get at the upload progress using your favorite AJAX library. Below is a small snippet of JavaScript that I am using in my demo app for getting at the status of the current upload.
intervalID = window.setInterval(function(){
var request = new Sys.Net.WebRequest();
request.set_url('UploadProgress.ashx?DJUploadStatus=' + token + '&ts=' + new Date().getTime());
request.set_httpVerb('GET');
request.add_completed(function(executor){
// the progress is returned as xml
var e = executor.get_xml().documentElement;
var empty = e.getAttribute('empty');
if(!empty){
// extract the attributes I am interested in
var percent = e.getAttribute('progress');
var file = e.getAttribute('file');
var kbs = Math.round(parseInt(e.getAttribute('bytes')) / 1024);
var size = Math.round(parseInt(e.getAttribute('size')) / 1024);
// update the progressbar to the new value
progressBar.set_percentage(percent);
// upadte the message
updateMessage('info', 'Uploading ' + file + ' ... ' + kbs + ' of ' + size + ' KB');
if(percent == 100){
// clear the interval
window.clearInterval(intervalID);
}
}
});
// invoke the request
request.invoke();
}, 1000);
Sample App
No live demo this time, but I do have a sample application. You can download it here.
Conclusion
Well, that's about it. I am curious, how have you handled file uploads in the web apps you have worked on? 3rd party component? Something home-grown? One of the components I mentioned above?
That's it. Enjoy!

If you're going to spend any time at the terminal, or want to start doing so, it should be a welcoming place. To go beyond green or white on black, check out this
You already know that prefixing a command with
Let's say a program, or web site, has just asked you to run a command to unlock or enable something, but you'd like to know just a little more before jumping in. Add
The
You can spend a lot of money and time hunting down a perfect backup app that works with all your systems just the way you want. Or you can spend a few minutes learning the basics of
Once you're comfortable with the terminal and getting good use from it, you might notice some of the more useful commands require an astute memory and typo-free typing—unless you make them shorter and easier. Start off by copying and pasting this command (on one line): 

If you've added a new item to your calendar and you want to force a new sync rather than waiting for Google Calendar Sync to run its next sync, just right-click the system tray app and choose Sync. It doesn't get much simpler than that.
Open iCal, then fire up your iCal Preferences (iCal -> Preferences or Cmd-,).
If you want to add a secondary calendar, the steps are exactly the same as above with one small difference. Instead of inserting your email address in the Account URL as described in step 4, you need to grab the calendar ID for that specific calendar. You can find it by opening GCal, clicking the arrow next to the calendar you want to sync, and selecting Calendar settings. In the settings, find the Calendar Address section near the bottom of the window, then just copy and paste the Calendar ID (which is formatted like an email address) in place of 
Whether your using Mozilla's standalone calendar application
Choose Google Calendar as the calendar type. The Location field requires the XML flavor of your calendar's Private Address, which you can get by opening GCal and choosing Calendar settings from the drop-down next to the calendar you want to access.
At the bottom of the settings page you'll see the Private Address section. Copy the XML link and paste it into the Location field in Sunbird or T-bird.
Alternatively, the free, open-source application