• <sub id="h4knl"><ol id="h4knl"></ol></sub>
    <sup id="h4knl"></sup>
      <sub id="h4knl"></sub>

      <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
      1. <strong id="h4knl"></strong>

      2. 通過Asp.Net的服務器控件上傳文件總結

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

        通過Asp.Net的服務器控件上傳文件總結

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

        通過Asp.Net的服務器控件上傳文件總結

          效果圖:

          本文涉及到的知識點:

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

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

          一、創建Html網頁

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

          復制代碼 代碼如下:

          二、實現文件上傳

          添加一個一般處理程序,命名為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屬性,修改之后的

          復制代碼 代碼如下:

          這樣文件上傳就完成了。

          三、實現文件上傳的進度顯示

          我的思路:

          文件上傳的處理過程中,是不可以在處理過程中將信息傳回客戶端的,只有當所有的處理都完畢之后才會傳回客戶端,所以如果是在上面的處理程序中寫 入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;

          ///

          /// 獲取或設置保存下載文件的百分比數值部分

          ///

          public long PercentNumber;

          public AsyncResult(HttpContext context, AsyncCallback callback)

          {

          this.context = context;

          this.callback = callback;

          }

          ///

          /// 向客戶端寫入信息

          ///

          public void Send()

          {

          this.context.Response.Write(PercentNumber);

          }

          ///

          /// 完成異步處理,結束請求

          ///

          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

          {

          ///

          /// 保存異步處理狀態信息的集合

          ///

          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添加如下代碼:

          復制代碼 代碼如下:

          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

          復制代碼 代碼如下:

          補充幾點:

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

          復制代碼 代碼如下:

          maxRequestLength的單位是KB

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

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

          源代碼下載:UploadFileDemo.rar

        《&.doc》
        将本文的Word文档下载到电脑,方便收藏和打印
        推荐度:
        点击下载文档

        【通過Asp.Net的服務器控件上傳文件總結】相關文章:

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

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

        美國研究生留學網申上傳文件類型09-05

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

        asp.net的學習過程講解07-11

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

        ASP.NET Page函數調用解析10-01

        監理文件資料的類型-監理文件資料分類10-22

        什么是DOS文件07-21

        如何使用ftp工具上傳網站內容?07-27

        在线咨询
        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码
      3. <sub id="h4knl"><ol id="h4knl"></ol></sub>
        <sup id="h4knl"></sup>
          <sub id="h4knl"></sub>

          <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
          1. <strong id="h4knl"></strong>

          2. 亚洲色一色l噜一噜噜噜 | 亚洲高清网址中文字幕 | 亚洲国产日韩欧美性 | 亚州第一中文字幕 | 中文字字幕乱码无线精品精品 | 亚洲国产日韩欧美综合久久 |

            通過Asp.Net的服務器控件上傳文件總結

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

            通過Asp.Net的服務器控件上傳文件總結

              效果圖:

              本文涉及到的知識點:

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

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

              一、創建Html網頁

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

              復制代碼 代碼如下:

              二、實現文件上傳

              添加一個一般處理程序,命名為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屬性,修改之后的

              復制代碼 代碼如下:

              這樣文件上傳就完成了。

              三、實現文件上傳的進度顯示

              我的思路:

              文件上傳的處理過程中,是不可以在處理過程中將信息傳回客戶端的,只有當所有的處理都完畢之后才會傳回客戶端,所以如果是在上面的處理程序中寫 入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;

              ///

              /// 獲取或設置保存下載文件的百分比數值部分

              ///

              public long PercentNumber;

              public AsyncResult(HttpContext context, AsyncCallback callback)

              {

              this.context = context;

              this.callback = callback;

              }

              ///

              /// 向客戶端寫入信息

              ///

              public void Send()

              {

              this.context.Response.Write(PercentNumber);

              }

              ///

              /// 完成異步處理,結束請求

              ///

              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

              {

              ///

              /// 保存異步處理狀態信息的集合

              ///

              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添加如下代碼:

              復制代碼 代碼如下:

              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

              復制代碼 代碼如下:

              補充幾點:

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

              復制代碼 代碼如下:

              maxRequestLength的單位是KB

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

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

              源代碼下載:UploadFileDemo.rar