I am trying to make a file upload handler in C # that is asynchronous and can provide updates on the progress of a file through asynchronous AJAX requests. Basically, if the request is POST, it loads some information into the session, and then starts loading, if the request was GET, it returns the current state of the load (bytes downloaded, general bytes, etc.). I'm not quite sure if this should be an asynchronous handler, but the files can be quite large, so I thought this would work best. For the base async handler, I used something very similar to the handler in this MSDN article . I have posted below some key sections of my code below. The problem I am facing is that I do not receive any GET information until the completion of the POST. I mentioned that in this example, I use jQuery for GET requests and BlueImp to publish the file.
HTML and JavaScript
<input id="somefile" type="file" /> $(function () { name = 'MyUniqueId130'; var int = null; $('#somefile').fileupload({ url: '/fileupload.axd?key='+name, done: function (e, data) { clearInterval(int); } }); $('#somefile').ajaxStart(function(){ int = setInterval(function(){ $.ajax({ url: '/fileupload.axd?key='+name, dataType: 'json', async: true }) .done(function(e1, data1){ if(!e1.InProgress || e1.Complete || e1.Canceled) clearInterval(int); }); }, 10000)}); });
The request method of an asynchronous process simply calls the correct method, whether it is POST or GET, one of the following, and then calls CompleteRequest to complete the request:
private static void GetFilesStatuses(HttpContext context) { string key = context.Request.QueryString["key"]; //A dictionary of <string, UploadStatus> in the session var Statuses = GetSessionStore(context); UploadStatus ups; if (!String.IsNullOrWhiteSpace(key)) { if (Statuses.TryGetValue(key, out ups)) { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Write(CreateJson(ups)); } else { context.Response.StatusCode = (int)HttpStatusCode.NotFound; } } else { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Write(CreateJson(Statuses.Values)); } } private static void UploadFile(HttpContext context) { var Statuses = GetSessionStore(context); string key = context.Request.QueryString["key"]; if (String.IsNullOrWhiteSpace(key)) { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; return; } HttpPostedFile file = context.Request.Files[0]; string extn = file.FileName.LastIndexOf('.') == -1 ? "" : file.FileName.Substring(file.FileName.LastIndexOf('.'), (file.FileName.Length - file.FileName.LastIndexOf('.'))); string temp = GetTempFileName(path, extn); UploadStatus status = new UploadStatus() { FileName = file.FileName, TempFileName = temp, Path = path, Complete = false, Canceled = false, InProgress = false, Success = true, BytesLoaded = 0, TotalBytes = file.ContentLength }; Statuses.Add(key, status); byte[] buffer = new byte[bufferSize]; int byteCount = 0; using (var fStream = System.IO.File.OpenWrite(context.Request.MapPath(path + temp))) { uploads.Add(status); while ((byteCount = file.InputStream.Read(buffer, 0, bufferSize)) > 0 && !status.Canceled) { status.InProgress = true; status.BytesLoaded += byteCount; fStream.Write(buffer, 0, byteCount); } status.Complete = !status.Canceled; status.InProgress = false; status.Success = true; if (status.Canceled) { Statuses.Remove(temp); } context.Response.StatusCode = (int)HttpStatusCode.OK; } }
I tried a lot of things, such as non-asynchronous handlers, async handlers, making sure JavaScript is running async, but for now I think I need different eyes on the problem, so thanks for any help anyone can provide.