中文字幕在线一区二区在线,久久久精品免费观看国产,无码日日模日日碰夜夜爽,天堂av在线最新版在线,日韩美精品无码一本二本三本,麻豆精品三级国产国语,精品无码AⅤ片,国产区在线观看视频

      通過Asp.Net的服務(wù)器控件上傳文件總結(jié)

      時間:2024-09-02 13:20:24 ASP 我要投稿
      • 相關(guān)推薦

      通過Asp.Net的服務(wù)器控件上傳文件總結(jié)

        相信通過Asp.Net的服務(wù)器控件上傳文件在簡單不過了,通過AjaxToolkit控件實現(xiàn)上傳進度也不是什么難事,為什么還要自己辛辛苦苦來 實現(xiàn)呢?我并不否認(rèn)”拿來主義“,只是我個人更喜歡凡是求個所以然。本篇將闡述通過Html,IHttpHandler和 IHttpAsyncHandler實現(xiàn)文件上傳和上傳進度的原理,希望對你有多幫助。

      通過Asp.Net的服務(wù)器控件上傳文件總結(jié)

        效果圖:

        本文涉及到的知識點:

        1.前臺用到Html,Ajax,JQuery,JQuery UI

        2.后臺用到一般處理程序(IHttpHandler)和一般異步處理程序(IHttpAsyncHandler),并涉及到”推模式“

        一、創(chuàng)建Html網(wǎng)頁

        1、在創(chuàng)建的Web工程中添加一個Html文件,命名為UploadFile.htm,在頭文件中引入JQuery,JQuery UI

        復(fù)制代碼 代碼如下:

        二、實現(xiàn)文件上傳

        添加一個一般處理程序,命名為UploadFileHandler.ashx

        復(fù)制代碼 代碼如下:

        public void ProcessRequest(HttpContext context)

        {

        //如果提交的文件名是空,則不處理

        if (context.Request.Files.Count == 0 || string.IsNullOrWhiteSpace(context.Request.Files[0].FileName))

        return;

        //獲取文件流

        Stream stream = context.Request.Files[0].InputStream;

        //獲取文件名稱

        string fileName = Path.GetFileName(context.Request.Files[0].FileName);

        //聲明字節(jié)數(shù)組

        byte[] buffer;

        //為什么是4096呢?這是操作系統(tǒng)中最小的分配空間,如果你的文件只有100個字節(jié),其實它占用的空間是4096個字節(jié)

        int bufferSize = 4096;

        //獲取上傳文件流的總長度

        long totalLength = stream.Length;

        //已經(jīng)寫入的字節(jié)數(shù),用于做上傳的百分比

        long writtenSize = 0;

        //創(chuàng)建文件

        using (FileStream fs = new FileStream(@"C:" + fileName, FileMode.Create, FileAccess.Write))

        {

        //如果寫入文件的字節(jié)數(shù)小于上傳的總字節(jié)數(shù),就一直寫,直到寫完為止

        while (writtenSize < totalLength)

        {

        //如果剩余的字節(jié)數(shù)不小于最小分配空間

        if (totalLength - writtenSize >= bufferSize)

        {

        //用最小分配空間創(chuàng)建新的字節(jié)數(shù)組

        buffer = new byte[bufferSize];

        }

        else

        //用剩余的字節(jié)數(shù)創(chuàng)建字節(jié)數(shù)組

        buffer = new byte[totalLength - writtenSize];

        //讀取上傳的文件到字節(jié)數(shù)組

        stream.Read(buffer, 0, buffer.Length);

        //將讀取的字節(jié)數(shù)組寫入到新建的文件流中

        fs.Write(buffer, 0, buffer.Length);

        //增加寫入的字節(jié)數(shù)

        writtenSize += buffer.Length;

        //計算當(dāng)前上傳文件的百分比

        long percent = writtenSize * 100 / totalLength;

        }

        }

        }

        在form中添加action和method屬性,修改之后的

        復(fù)制代碼 代碼如下:

        這樣文件上傳就完成了。

        三、實現(xiàn)文件上傳的進度顯示

        我的思路:

        文件上傳的處理過程中,是不可以在處理過程中將信息傳回客戶端的,只有當(dāng)所有的處理都完畢之后才會傳回客戶端,所以如果是在上面的處理程序中寫 入context.Response.Write(percent);是不可能得到處理的過程,只能等到處理結(jié)束后,客戶端一次性得到所有的值。

        要想得到處理過程中的值,我的解決是這樣,在文件上傳時,要開啟另一個請求,來獲取進度信息。而這個請求是異步的,我指的是客戶端異步請求和服 務(wù)端異步處理。因為要涉及到兩個不同的請求處理程序之間信息的傳遞,將"處理文件上傳的程序"得到的進度信息傳遞給"處理進度請求的程序",而"處理進度 請求的處理程序"要依賴于"處理文件上傳的處理程序"。處理圖:

        首先客戶端同時(幾乎是)發(fā)出兩個請求,一個是文件上傳,一個是進度請求。由于"處理請求進度的程序"是異步處理的,當(dāng)該程序沒有信息發(fā)給客戶 端時,我們讓它處于等待狀態(tài),這里有點像Tcp,這樣客戶端跟服務(wù)器就一直處于連接狀態(tài)。當(dāng)"處理文件上傳的程序"開始處理時,通過把進度值賦值給"處理 請求進度程序"的異步操作的狀態(tài),并觸發(fā)"處理請求進度的程序"返回值給客戶端?蛻舳双@取進度值,并處理。這樣一次請求進度值的請求就結(jié)束了,我們知道 服務(wù)器是不會主動給客戶端發(fā)送信息的,只有客戶端請求,服務(wù)器才會響應(yīng)。顯然,要想在文件保存的過程中向客戶端發(fā)送進度信息,客戶端得到每得到一個返回結(jié) 果,都是一次請求。為了得到連續(xù)的請求值,客戶端再向"處理請求進度的程序"發(fā)出請求,依次循環(huán),知道文件上傳結(jié)束。

        技術(shù)實現(xiàn):

        異步處理用到接口IHttpAsyncHandler,新建一個一般處理程序,命名為RequestProgressAsyncHandler.ashx,將默認(rèn)的接口改為IHttpAsyncHandler

        復(fù)制代碼 代碼如下:

        public class RequestProgressAsyncHandler : IHttpAsyncHandler

        {

        public void ProcessRequest(HttpContext context)

        {

        }

        public bool IsReusable

        {

        get

        {

        return false;

        }

        }

        #region IHttpAsyncHandler 成員

        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)

        {

        throw new NotImplementedException();

        }

        public void EndProcessRequest(IAsyncResult result)

        {

        throw new NotImplementedException();

        }

        #endregion

        }

        BeginProcessRequest和EndProcessRequest是兩個核心的方法,其他的兩個不用處理。當(dāng)該處理程序處理請求 時,BeginProcessRequest是第一個被調(diào)用的函數(shù),返回一個包含異步狀態(tài)信息的對象,該對象是IAsyncResult類型,是實現(xiàn)異步 的關(guān)鍵,用于控制什么時候調(diào)用EndProcessRequest來結(jié)束處理程序的等待狀態(tài),BeginProcessRequest被調(diào)用之后,程序就 處于等待狀態(tài)。EndProcessRequest是在結(jié)束請求時的處理函數(shù),通過該函數(shù)可以向客戶端寫入信息。

        實現(xiàn)接口IAsyncResult

        復(fù)制代碼 代碼如下:

        public class AsyncResult : IAsyncResult

        {

        // 標(biāo)示異步處理的狀態(tài)

        private bool isComplete = false;

        //保存異步處理程序中的Http上下文

        private HttpContext context;

        //異步回調(diào)的委托

        private AsyncCallback callback;

        ///

        /// 獲取或設(shè)置保存下載文件的百分比數(shù)值部分

        ///

        public long PercentNumber;

        public AsyncResult(HttpContext context, AsyncCallback callback)

        {

        this.context = context;

        this.callback = callback;

        }

        ///

        /// 向客戶端寫入信息

        ///

        public void Send()

        {

        this.context.Response.Write(PercentNumber);

        }

        ///

        /// 完成異步處理,結(jié)束請求

        ///

        public void DoCompleteTask()

        {

        if (callback != null)

        callback(this);//會觸發(fā)處理程序中的EndProcessRequest函數(shù),結(jié)束請求

        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

        }

        修改 RequestProgressAsyncHandler.ashx文件:

        復(fù)制代碼 代碼如下:

        public class RequestProgressAsyncHandler : IHttpAsyncHandler

        {

        ///

        /// 保存異步處理狀態(tài)信息的集合

        ///

        public static ListAsyncResults = new List();

        public void ProcessRequest(HttpContext context)

        {

        }

        public bool IsReusable

        {

        get

        {

        return false;

        }

        }

        #region IHttpAsyncHandler 成員

        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)

        {

        //保證集合中只用一個元素

        AsyncResults.Clear();

        AsyncResult ar = (AsyncResult)result;

        ar.Send();

        }

        #endregion

        }

        在UploadFileHandler.ashx添加如下代碼:

        復(fù)制代碼 代碼如下:

        private static void SendPercentToClient(long percent)

        {

        //當(dāng)上傳完畢后,保證處理程序能向客戶端傳回

        while (RequestProgressAsyncHandler.AsyncResults.Count == 0 && percent == 100)

        {

        }

        //因為本處理程序和"處理請求進度的程序"是并發(fā)的,不能保證RequestProgressAsyncHandler.AsyncResults一定含有子項

        if (RequestProgressAsyncHandler.AsyncResults.Count != 0)

        {

        RequestProgressAsyncHandler.AsyncResults[0].PercentNumber = percent;

        RequestProgressAsyncHandler.AsyncResults[0].DoCompleteTask();

        }

        }

        在函數(shù)ProcessRequest中加入以上方法:

        復(fù)制代碼 代碼如下:

        ...

        ...

        //計算當(dāng)前上傳文件的百分比

        long percent = writtenSize * 100 / totalLength;

        SendPercentToClient(percent);

        服務(wù)端OK!修改客戶端,添加JS處理函數(shù):

        復(fù)制代碼 代碼如下:

        function RequestProgress() {

        $.post("RequestProgressAsyncHandler.ashx", function (data, status) {

        if (status == "success") {

        $("#progressValue").text(data + "%");

        data = parseInt(data);

        $("#progressBar").progressbar({ value: data });//JQuery UI 設(shè)置進度條值

        //如果進度不是 100,則重新請求

        if (data != 100) {

        RequestProgress();

        }

        }

        });

        }

        在form中添加事件omsubmit的處理函數(shù)為RequestProgress

        復(fù)制代碼 代碼如下:

        補充幾點:

        1.默認(rèn)Asp.Net允許的上傳文件的大小是4M,可以在Web.config中修改其大小限制

        復(fù)制代碼 代碼如下:

        maxRequestLength的單位是KB

        2.在IE 8.0測試中,在文件上傳完畢后,狀態(tài)欄還處于請求中

        反正不是后臺還在請求,這個放心,只要把鼠標(biāo)在按鈕和瀏覽上面來回移動幾下就沒了,可能是JQuery UI 的問題。FF和Chrom下沒這個問題,就是顯示效果會有點差,但是上傳沒問題的。

        源代碼下載:UploadFileDemo.rar

      【通過Asp.Net的服務(wù)器控件上傳文件總結(jié)】相關(guān)文章:

      限制文件下載時上傳速度10-22

      ASP的chr(0)文件上傳漏洞原理及解決方案05-21

      美國研究生留學(xué)網(wǎng)申上傳文件類型09-05

      ACCA注冊需要上傳的資料10-04

      asp.net的學(xué)習(xí)過程講解07-11

      ASP.NET MVC異常處理模塊簡單教程-ASP.NET教程實例推薦07-19

      ASP.NET Page函數(shù)調(diào)用解析10-01

      監(jiān)理文件資料的類型-監(jiān)理文件資料分類10-22

      什么是DOS文件07-21

      如何使用ftp工具上傳網(wǎng)站內(nèi)容?07-27

      主站蜘蛛池模板: 国产超碰人人一区二区三区| 看黄色亚洲看黄色亚洲| 亚洲毛片美女毛片美女| 一本加勒比hezyo无码视频| 国产高清精品在线二区| 国产日产亚洲系列av| 呼玛县| 国产精品无码久久AⅤ人妖| 91综合久久婷婷久久| 女同在线观看免费网站| 国产高潮自拍视频在线观看| 91久国产在线观看| 国产精品日韩中文字幕| 亚洲一区二区三区熟女少妇| 亚洲精品一区二区三区四| 榆树市| 双峰县| 台中县| 中文字幕亚洲乱亚洲乱妇| 国产乱子伦农村xxxx| 精品国产迪丽热巴在线| 国产毛片A啊久久久久| 扒开非洲女人大荫蒂视频| 加勒比熟女精品一区二区av| 久久久一本精品99久久| 电白县| 绍兴县| 沂源县| 正镶白旗| 常熟市| 国产一区二区三区韩国| 房产| 香河县| 免费视频一区二区三区亚洲激情| 景德镇市| av一区二区精品在线| 石台县| 国产一区二区欧美丝袜| 九九在线精品视频xxx| 婷婷色在线视频中文字幕| 91精品国产综合久久青草|