我想在C#中創建一個異步的文件上傳處理程序,並且可以通過AJAX異步請求提供文件進度更新。基本上,如果請求是POST,它會將一些信息加載到會話中,然後開始上傳,如果請求是GET,它會返回上傳的當前狀態(上傳的字節數,總字節數等)。我並不完全確定它需要是一個異步處理程序,但文件可能非常大,所以我認爲這最好。對於基礎異步處理程序,我使用了與此處理程序非常相似的東西,內容如下:MSDN article。我在下面發佈了我的代碼的一些關鍵部分。我遇到的問題是,在POST完成之前,我沒有收到任何GET信息。我會提到在這個例子中,我使用jQuery作爲GET請求,使用BlueImp來發布文件。ASP.Net異步HTTP文件上傳處理程序
的HTML和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)});
});
異步處理請求方法只是調用正確的方法是否是一個POST或GET來的那麼下面的調用CompleteRequest結束請求之一:
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;
}
}
我已經嘗試了許多事情,例如非異步處理程序,異步處理程序,確保JavaScript運行異步,但此時我認爲我需要一些不同的眼睛來解決問題,所以感謝您提供任何人都可以提供的幫助。
在遇到此問題的情況下,我創建了一個靜態ConcurrentDictionary,並在while循環內添加了一個TryUpdate來更新狀態。這固定的大部分問題,但我也改變了JavaScript使用BlueImps beforeSend函數來啓動異步請求 – ars265