相信通過Asp.Net的服務(wù)器控件上傳文件在簡(jiǎn)單不過了,通過AjaxToolkit控件實(shí)現(xiàn)上傳進(jìn)度也不是什么難事,為什么還要自己辛辛苦苦來 實(shí)現(xiàn)呢?我并不否認(rèn)”拿來主義“,只是我個(gè)人更喜歡凡是求個(gè)所以然。本篇將闡述通過Html,IHttpHandler和 IHttpAsyncHandler實(shí)現(xiàn)文件上傳和上傳進(jìn)度的原理,希望對(duì)你有多幫助。
效果圖:
本文涉及到的知識(shí)點(diǎn):
1.前臺(tái)用到Html,Ajax,JQuery,JQuery UI
2.后臺(tái)用到一般處理程序(IHttpHandler)和一般異步處理程序(IHttpAsyncHandler),并涉及到”推模式“
一、創(chuàng)建Html網(wǎng)頁
1、在創(chuàng)建的Web工程中添加一個(gè)Html文件,命名為UploadFile.htm,在頭文件中引入JQuery,JQuery UI
通過Ajax是不能上傳文件的,無刷新上傳是靠隱藏的iframe來實(shí)現(xiàn)的
在JS中加入如下處理:
二、實(shí)現(xiàn)文件上傳
添加一個(gè)一般處理程序,命名為UploadFileHandler.ashx
三、實(shí)現(xiàn)文件上傳的進(jìn)度顯示
我的思路:
文件上傳的處理過程中,是不可以在處理過程中將信息傳回客戶端的,只有當(dāng)所有的處理都完畢之后才會(huì)傳回客戶端,所以如果是在上面的處理程序中寫 入context.Response.Write(percent);是不可能得到處理的過程,只能等到處理結(jié)束后,客戶端一次性得到所有的值。
要想得到處理過程中的值,我的解決是這樣,在文件上傳時(shí),要開啟另一個(gè)請(qǐng)求,來獲取進(jìn)度信息。而這個(gè)請(qǐng)求是異步的,我指的是客戶端異步請(qǐng)求和服 務(wù)端異步處理。因?yàn)橐婕暗絻蓚€(gè)不同的請(qǐng)求處理程序之間信息的傳遞,將"處理文件上傳的程序"得到的進(jìn)度信息傳遞給"處理進(jìn)度請(qǐng)求的程序",而"處理進(jìn)度 請(qǐng)求的處理程序"要依賴于"處理文件上傳的處理程序"。處理圖:
首先客戶端同時(shí)(幾乎是)發(fā)出兩個(gè)請(qǐng)求,一個(gè)是文件上傳,一個(gè)是進(jìn)度請(qǐng)求。由于"處理請(qǐng)求進(jìn)度的程序"是異步處理的,當(dāng)該程序沒有信息發(fā)給客戶 端時(shí),我們讓它處于等待狀態(tài),這里有點(diǎn)像Tcp,這樣客戶端跟服務(wù)器就一直處于連接狀態(tài)。當(dāng)"處理文件上傳的程序"開始處理時(shí),通過把進(jìn)度值賦值給"處理 請(qǐng)求進(jìn)度程序"的異步操作的狀態(tài),并觸發(fā)"處理請(qǐng)求進(jìn)度的程序"返回值給客戶端。客戶端獲取進(jìn)度值,并處理。這樣一次請(qǐng)求進(jìn)度值的請(qǐng)求就結(jié)束了,我們知道 服務(wù)器是不會(huì)主動(dòng)給客戶端發(fā)送信息的,只有客戶端請(qǐng)求,服務(wù)器才會(huì)響應(yīng)。顯然,要想在文件保存的過程中向客戶端發(fā)送進(jìn)度信息,客戶端得到每得到一個(gè)返回結(jié) 果,都是一次請(qǐng)求。為了得到連續(xù)的請(qǐng)求值,客戶端再向"處理請(qǐng)求進(jìn)度的程序"發(fā)出請(qǐng)求,依次循環(huán),知道文件上傳結(jié)束。
技術(shù)實(shí)現(xiàn):
異步處理用到接口IHttpAsyncHandler,新建一個(gè)一般處理程序,命名為RequestProgressAsyncHandler.ashx,將默認(rèn)的接口改為IHttpAsyncHandler
實(shí)現(xiàn)接口IAsyncResult
//保存異步處理程序中的Http上下文
private HttpContext context;
//異步回調(diào)的委托
private AsyncCallback callback;
/// summary>
/// 獲取或設(shè)置保存下載文件的百分比數(shù)值部分
/// /summary>
public long PercentNumber;
public AsyncResult(HttpContext context, AsyncCallback callback)
{
this.context = context;
this.callback = callback;
}
/// summary>
/// 向客戶端寫入信息
/// /summary>
public void Send()
{
this.context.Response.Write(PercentNumber);
}
/// summary>
/// 完成異步處理,結(jié)束請(qǐng)求
/// /summary>
public void DoCompleteTask()
{
if (callback != null)
callback(this);//會(huì)觸發(fā)處理程序中的EndProcessRequest函數(shù),結(jié)束請(qǐng)求
this.isComplete = true;
}
#region IAsyncResult 成員
public object AsyncState
{
get { return null; }
}
public System.Threading.WaitHandle AsyncWaitHandle
{
get { return null; }
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return isComplete; }
}
#endregion
}
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
AsyncResult result = new AsyncResult(context, cb);
AsyncResults.Add(result);
return result;
}
public void EndProcessRequest(IAsyncResult result)
{
//保證集合中只用一個(gè)元素
AsyncResults.Clear();
AsyncResult ar = (AsyncResult)result;
ar.Send();
}
#endregion
}
}
//因?yàn)楸咎幚沓绦蚝?處理請(qǐng)求進(jìn)度的程序"是并發(fā)的,不能保證RequestProgressAsyncHandler.AsyncResults一定含有子項(xiàng)
if (RequestProgressAsyncHandler.AsyncResults.Count != 0)
{
RequestProgressAsyncHandler.AsyncResults[0].PercentNumber = percent;
RequestProgressAsyncHandler.AsyncResults[0].DoCompleteTask();
}
}
SendPercentToClient(percent);
2.在IE 8.0測(cè)試中,在文件上傳完畢后,狀態(tài)欄還處于請(qǐng)求中
反正不是后臺(tái)還在請(qǐng)求,這個(gè)放心,只要把鼠標(biāo)在按鈕和瀏覽上面來回移動(dòng)幾下就沒了,可能是JQuery UI 的問題。FF和Chrom下沒這個(gè)問題,就是顯示效果會(huì)有點(diǎn)差,但是上傳沒問題的。
源代碼下載:UploadFileDemo.rar
標(biāo)簽:岳陽 西寧 西藏 紅河 衢州 宣城 湖州 福州
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Asp.Net 無刷新文件上傳并顯示進(jìn)度條的實(shí)現(xiàn)方法及思路》,本文關(guān)鍵詞 Asp.Net,無,刷新,文件,上傳,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。