<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路

        來源:懂視網 責編:小采 時間:2020-11-27 22:40:44
        文檔

        Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路

        Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路:相信通過Asp.Net的服務器控件上傳文件在簡單不過了,通過AjaxToolkit控件實現上傳進度也不是什么難事,為什么還要自己辛辛苦苦來 實現呢?我并不否認拿來主義,只是我個人更喜歡凡是求個所以然。本篇將闡述通過Html,IHttpHandler和 IHttpAs
        推薦度:
        導讀Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路:相信通過Asp.Net的服務器控件上傳文件在簡單不過了,通過AjaxToolkit控件實現上傳進度也不是什么難事,為什么還要自己辛辛苦苦來 實現呢?我并不否認拿來主義,只是我個人更喜歡凡是求個所以然。本篇將闡述通過Html,IHttpHandler和 IHttpAs

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

        效果圖:

        本文涉及到的知識點:
        1.前臺用到Html,Ajax,JQuery,JQuery UI

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

        一、創建Html網頁
        1、在創建的Web工程中添加一個Html文件,命名為UploadFile.htm,在頭文件中引入JQuery,JQuery UI
        代碼如下:
        <link href="Styles/jquery-ui-1.8.16.custom.css" rel="stylesheet" type="text/css" />
            <script src="Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
            <script src="Scripts/jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script>

        2、關于無刷新文件上傳

        通過Ajax是不能上傳文件的,無刷新上傳是靠隱藏的iframe來實現的
        代碼如下:
        <form id="form" target = "frameFileUpload" enctype="multipart/form-data">
        <div id="progressBar" style="font-size: 1em;"></div>
        <input type="file" id="fileUpload" name="fileUpload" /><span id="progressValue"></span>
        <iframe id="frameFileUpload" name="frameFileUpload" style="display:none;" ></iframe>
        <br />
        <input type="submit" value="上傳" id = "submit"/>
        </form>

        要將form標簽的target屬性設置為iframe的id,當然別忘了將form的enctype設置為multipart/form-data
        代碼如下:
        <div id="progressBar" style="font-size: 1em;"></div>

        是用來顯示上傳文件時的進度條

        在JS中加入如下處理:
        代碼如下:
            <script type="text/javascript">
                $(function () {
                    $("#submit").button();
                    $("#fileUpload").button();
                });
            </script>

        此時效果:

        二、實現文件上傳
        添加一個一般處理程序,命名為UploadFileHandler.ashx
        代碼如下:
                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);
                    //聲明字節數組
                    byte[] buffer;
                    //為什么是4096呢?這是操作系統中最小的分配空間,如果你的文件只有100個字節,其實它占用的空間是4096個字節
                    int bufferSize = 4096;
                    //獲取上傳文件流的總長度
                    long totalLength = stream.Length;
                    //已經寫入的字節數,用于做上傳的百分比
                    long writtenSize = 0;
                    //創建文件
                    using (FileStream fs = new FileStream(@"C:\" + fileName, FileMode.Create, FileAccess.Write))
                    {
                        //如果寫入文件的字節數小于上傳的總字節數,就一直寫,直到寫完為止
                        while (writtenSize < totalLength)
                        {
                            //如果剩余的字節數不小于最小分配空間
                            if (totalLength - writtenSize >= bufferSize)
                            {
                                //用最小分配空間創建新的字節數組
                                buffer = new byte[bufferSize];
                            }
                            else
                                //用剩余的字節數創建字節數組
                                buffer = new byte[totalLength - writtenSize];
                            //讀取上傳的文件到字節數組
                            stream.Read(buffer, 0, buffer.Length);
                            //將讀取的字節數組寫入到新建的文件流中
                            fs.Write(buffer, 0, buffer.Length);
                            //增加寫入的字節數
                            writtenSize += buffer.Length;
                            //計算當前上傳文件的百分比
                            long percent = writtenSize * 100 / totalLength;
                        }
                    }
                }

        在form中添加action和method屬性,修改之后的
        代碼如下:
        <form action="UploadFileHandler.ashx" method="post" id="form" target = "frameFileUpload" enctype="multipart/form-data">

        這樣文件上傳就完成了。

        三、實現文件上傳的進度顯示
        我的思路:

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

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

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

        技術實現:
          異步處理用到接口IHttpAsyncHandler,新建一個一般處理程序,命名為RequestProgressAsyncHandler.ashx,將默認的接口改為IHttpAsyncHandler
        代碼如下:
            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是兩個核心的方法,其他的兩個不用處理。當該處理程序處理請求 時,BeginProcessRequest是第一個被調用的函數,返回一個包含異步狀態信息的對象,該對象是IAsyncResult類型,是實現異步 的關鍵,用于控制什么時候調用EndProcessRequest來結束處理程序的等待狀態,BeginProcessRequest被調用之后,程序就 處于等待狀態。EndProcessRequest是在結束請求時的處理函數,通過該函數可以向客戶端寫入信息。

        實現接口IAsyncResult

        代碼如下:
            public class AsyncResult : IAsyncResult
            {
                // 標示異步處理的狀態
                private bool isComplete = false;

                //保存異步處理程序中的Http上下文
                private HttpContext context;

                //異步回調的委托
                private AsyncCallback callback;
                /// <summary>
                /// 獲取或設置保存下載文件的百分比數值部分
                /// </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>
                /// 完成異步處理,結束請求
                /// </summary>
                public void DoCompleteTask()
                {
                    if (callback != null)
                        callback(this);//會觸發處理程序中的EndProcessRequest函數,結束請求
                    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文件:
        代碼如下:
            public class RequestProgressAsyncHandler : IHttpAsyncHandler
            {
                /// <summary>
                /// 保存異步處理狀態信息的集合
                /// </summary>
                public static List<AsyncResult> AsyncResults = new List<AsyncResult>();
                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添加如下代碼:
        代碼如下:
                private static void SendPercentToClient(long percent)
                {
                    //當上傳完畢后,保證處理程序能向客戶端傳回
                    while (RequestProgressAsyncHandler.AsyncResults.Count == 0 && percent == 100)
                    {

                    }
                    //因為本處理程序和"處理請求進度的程序"是并發的,不能保證RequestProgressAsyncHandler.AsyncResults一定含有子項
                    if (RequestProgressAsyncHandler.AsyncResults.Count != 0)
                    {
                        RequestProgressAsyncHandler.AsyncResults[0].PercentNumber = percent;
                        RequestProgressAsyncHandler.AsyncResults[0].DoCompleteTask();
                    }
                }

        在函數ProcessRequest中加入以上方法:
        代碼如下:
                     ...
                             ...
                     //計算當前上傳文件的百分比
                            long percent = writtenSize * 100 / totalLength;

                            SendPercentToClient(percent);

        服務端OK!修改客戶端,添加JS處理函數:
        代碼如下:
                function RequestProgress() {
                    $.post("RequestProgressAsyncHandler.ashx", function (data, status) {
                        if (status == "success") {
                            $("#progressValue").text(data + "%");
                            data = parseInt(data);
                            $("#progressBar").progressbar({ value: data });//JQuery UI 設置進度條值
                            //如果進度不是 100,則重新請求
                            if (data != 100) {
                                RequestProgress();
                            }
                        }
                    });
                }

        在form中添加事件omsubmit的處理函數為RequestProgress
        代碼如下:
        <form action="UploadFileHandler.ashx" onsubmit = "RequestProgress();" method="post" id="form" target = "frameFileUpload" enctype="multipart/form-data">

        補充幾點:
        1.默認Asp.Net允許的上傳文件的大小是4M,可以在Web.config中修改其大小限制
        代碼如下:
            <system.web>
                <httpRuntime maxRequestLength="444444"/>
            </system.web>

        maxRequestLength的單位是KB

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

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

        源代碼下載:UploadFileDemo.rar

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路

        Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路:相信通過Asp.Net的服務器控件上傳文件在簡單不過了,通過AjaxToolkit控件實現上傳進度也不是什么難事,為什么還要自己辛辛苦苦來 實現呢?我并不否認拿來主義,只是我個人更喜歡凡是求個所以然。本篇將闡述通過Html,IHttpHandler和 IHttpAs
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 四虎永久在线精品免费观看地址 | 四虎在线免费播放| 亚洲大香伊人蕉在人依线| 91麻豆国产免费观看| 4444亚洲国产成人精品| 一区二区三区在线免费看| 色婷婷六月亚洲婷婷丁香| 亚州免费一级毛片| 国产精品亚洲专区在线观看 | 国产在线观看免费完整版中文版| 一区二区亚洲精品精华液| 日本人护士免费xxxx视频| 免费看一级一级人妻片| 亚洲色成人中文字幕网站| 久9热免费精品视频在线观看| 99久久精品国产亚洲| 成年人免费网站在线观看| 久久无码av亚洲精品色午夜| 亚洲国产综合精品中文字幕| 国产在线观看无码免费视频| 亚洲精品私拍国产福利在线| aa级一级天堂片免费观看| 美女无遮挡免费视频网站| 亚洲色精品vr一区二区三区| 亚洲啪啪免费视频| 国产精品亚洲专区无码WEB| 精品亚洲一区二区三区在线播放| 免费在线中文日本| 色婷五月综激情亚洲综合| 亚洲国产精品毛片av不卡在线| a级毛片免费观看视频| 久久亚洲最大成人网4438| 亚洲 无码 在线 专区| 性xxxxx大片免费视频| 亚洲综合精品成人| 亚洲午夜国产精品无码 | 一级一片免费视频播放| 亚洲国产一区二区a毛片| 国产成人精品免费直播| 日本视频在线观看永久免费| 亚洲熟女www一区二区三区|