I hate file uploaders. The simplest way is always the ugliest, and having anything "nice" requires days of backbreaking labour, and even then you're not even close to being sure it will work across all browsers. It's frustrating to do so much work and then have some users receive seemingly random errors for no apparent reason!
Matt pointed this neat file uploader out to me the other day, plupload. It is very simple and has about a half dozen "fallbacks" for supporting different technologies from Google Gears, Flash and HTML5.
For the most part implementing plupload is a matter of downloading the zip, unzipping and whacking in some sample code. But there IS a catch. Plupload uses BINAY STREAMING, not your bog standard multipart upload. So if you're hoping for a simple drag and drop replacement for your existing code, sorry to disappoint. But it's not that hard to convert your existing app into a binary stream app!
Of course, there is an easy PHP implementation from the folks that wrote plupload, but I really struggled to find an ASP.NET one. So here's one I wrote based loosely on the PHP version! This is not complete by any stretch (you'd want to handle caching, I/O errors, folder creation etc), but this is the guts of it to save you some research.
Two main things you'll want to take note of.
1. Plupload supports chunks - this is a way to get around upload file size restrictions. Basically, the file can be chopped up and sent as multiple parts, and then put back together again when it arrives. If you look at the requests going to the server, you will see there are actually multiple requests PER FILE. This means we need to stitch the files together when we're done at the other end.
2. Data handling - plupload stores the file name, and chunk info into the querystring, and all the file data is in Request.InputStream...so don't bother trying to work out why Request.Files is empty!
Here is the basics of what you need to implement plupload in asp.net! Easy as! If you're using any other file uploader, change it NOW!
int chunk = Request.QueryString["chunk"] != null ? int.Parse(Request.QueryString["chunk"]) : 0;
//open a file, if our chunk is 1 or more, we should be appending to an existing file, otherwise create a new file FileStream fs = new FileStream(Server.MapPath("/files/" + fileName), chunk == 0 ? FileMode.OpenOrCreate : FileMode.Append); //write our input stream to a buffer
Byte buffer = new Byte[Request.InputStream.Length]; Request.InputStream.Read(buffer, 0, buffer.Length);
string fileName = Request.QueryString["name"] != null ? Request.QueryString["name"] : ""; //write the buffer to a file.
fs.Write(buffer, 0, buffer.Length);
Of course, if you're REALLY lazy, they've just recently updated plupload to support multipart uploads...but that's just boring!