asp.net單檔案帶進度條上傳的解決方案_實用技巧

來源:互聯網
上載者:User

最近做項目中遇到很多問題,比如帶進度條的檔案上傳,看了網上很多資料還沒找到真正意義上的ASP.NET實現進度條上傳(可能是我沒找到),下面我來跟大家分享一下我實現的這個程式。
首先看下介面效果,當然你可以完全修改介面為你自己所用。

先解釋一下這個程式,該程式採用了jquery架構,實現了小檔案上傳,不超過80Mb,可以在web.config檔案中進行相應的配置,但是有個最大值,具體需要查看msdn。開發環境採用visual studio 2013 .net framework 4.5,啟動並執行時候大家注意一下是否滿足要求,好了,下面直入正題。
先來看看實現原理。基本原理:一個頁面進行檔案上傳,另外一個頁面去監聽這個檔案上傳了多少。
這裡面有兩個地方需要解釋一下:第一個,如何知道監聽的這個檔案就是上傳的這個檔案?實現機制很簡單,就是讓asp.net產生一個唯一的guid,這個id序號是唯一的,通過ajax取出來賦值給一個隱藏欄位;第二個,如何擷取guid標誌的檔案資訊?通過asp.net緩衝機制實現,上傳的過程中,不斷的將上傳資訊往緩衝裡面寫,直到檔案上傳完成,而在另外一個通過guid擷取緩衝的資訊,資訊包括你想要的資訊,比如上傳了多少位元組、消耗了多長時間等。好了,要點就解釋到這裡,有疑問的話給我留言。
下面來說說具體的實現:
檔案目錄結構如下:

 

index.htm就是檔案上傳頁面,提交form給UploadHandler目錄下的Default.aspx,以實現檔案上傳。
ProgressHandler目錄下三個檔案為Abort.ashx、GenericGuid.ashx,Handler.ashx功能分別為:根據Guid取消正在上傳的檔案,產生Guid,根據Guid擷取上傳資訊。
第一步:建立index.htm頁面,這個上傳頁面,需要注意的就是需要一個隱藏的iframe,並且名字為form提交的目標。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="http://www.w3.org/1999/xhtml"> <head>  <title>ASP.NET Ajax檔案上傳進度條樣本</title>  <meta name="author" content="李檢全" />  <link href="Styles/base.css" rel="stylesheet" type="text/css" />  <script src="Scripts/jquery-1.4.2.min.js" type="text/javascript"></script>  <script src="Scripts/jquery-ui-1.8.2.custom.min.js" type="text/javascript"></script>  <script src="Scripts/ljq.lib.js" type="text/javascript"></script>  <script src="Scripts/Ajax/GuidGet.js" type="text/javascript"></script>  <script src="Scripts/Ajax/ajax-progress-upload.js" type="text/javascript"></script> </head> <body>  <div id="upload_demo">   <div class="title">ASP.NET Ajax 檔案上傳進度條樣本</div>   <form action="UploadHandler/Default.aspx" enctype="multipart/form-data" method="post" target="upload_hidden_iframe">    <input id="guid" name="guid" value="" type="hidden" />    <p>*本程式適合小檔案上傳,不超過80Mb</p>    <p>檔案地址</p>    <input name="upload_file" type="file" />    <br />    <p>檔案描述</p>    <textarea name="description_file"></textarea>    <br />    <br />    <input type="submit" value="上傳檔案" />   </form>  </div>  <div id="back_panel"></div>  <div id="upload_panel">   <div id="upload_title">檔案上傳</div>   <div id="upload_content">     <ul>     <li id="finished_percent">正在準備上傳...</li>     <li><div id="upload_bar"><div id="upload_progress"></div></div></li>     <li id="upload_speed"></li>     <li id="upload_costTime"></li>     <li id="upload_fileSize"></li>     <li id="upload_fileName"></li>    </ul>     <div id="upload_detail"></div>    <div id="upload_choose">     <span id="upload_cancel">取消</span><span id="upload_submit">確定</span>    </div>   </div>  </div>  <iframe name="upload_hidden_iframe" style="display:none;"></iframe>   </body> </html> 

第二步,建立GenerateGuid.ashx檔案,作用就是產生唯一的Guid。

<%@ WebHandler Language="C#" Class="ProgressHandler.Handler" %>  using System; using System.Web; using System.Xml.Linq;  namespace ProgressHandler {  public class Handler : IHttpHandler  {   /// <summary>   /// 獲得上傳檔案的GUID   /// </summary>   /// <param name="context">當前請求實體</param>   /// <creattime>2015-06-28</creattime>   /// <author>FreshMan</author>   public void ProcessRequest(HttpContext context)   {    context.Response.Charset = "utf-8";    context.Response.ContentType = "application/xml";    var guid = Guid.NewGuid().ToString();    var doc = new XDocument();    var root = new XElement("root");     var xGuid = new XElement("guid", guid);    root.Add(xGuid);    doc.Add(root);    context.Response.Write(doc.ToString());    context.Response.End();   }    public bool IsReusable   {    get { return false; }   }   } } 

第三步,建立Default.aspx檔案,用於提交表單時上傳檔案。

using System;  namespace UploadHandler {  public partial class UploadHandlerDefault : System.Web.UI.Page  {   protected void Page_Load(object sender, EventArgs e)   {    string guid = Request.Params["guid"];    UploadUtil utilHelp = new UploadUtil(this, guid);    utilHelp.Upload();   }  } } 

上傳核心代碼:

using System; using System.Web; using System.IO; using System.Configuration; using System.Web.UI; using System.Web.Caching; using System.Threading; public class UploadUtil {  private Stream _reader;  private FileStream _fStream;  private const int Buffersize = 10000;  private readonly string _filePath =new Page().Server.MapPath(ConfigurationManager.AppSettings["upload_folder"]);  private readonly Page _page;  private readonly string _guid;  public UploadUtil(Page page, string guid)  {   _page = page;   _guid = guid;  }  public void Upload()  {   if (_page.Request.Files.Count > 0)   {    DoUpload(_page.Request.Files[0]);   }  }  private void DoUpload(HttpPostedFile postedFile)  {   bool abort = false;   string uploadFilePath = _filePath + DateTime.Now.ToFileTime()+"//";   if (!Directory.Exists(uploadFilePath))   {    Directory.CreateDirectory(uploadFilePath);   }   string uploadFileName = postedFile.FileName;   DownloadingFileInfo info = new DownloadingFileInfo(uploadFileName, postedFile.ContentLength, postedFile.ContentType);   object fileObj = HttpContext.Current.Cache[_guid];   if (fileObj != null)   {    HttpContext.Current.Cache.Remove(_guid);   }   HttpContext.Current.Cache.Add(_guid, info, null, DateTime.Now.AddDays(1), TimeSpan.Zero, CacheItemPriority.AboveNormal, null);   DateTime begin=DateTime.Now.ToLocalTime();   _fStream = new FileStream(uploadFilePath + uploadFileName, FileMode.Create);   _reader = postedFile.InputStream;   byte []buffer=new byte[Buffersize];   int len = _reader.Read(buffer,0,Buffersize);    while (len > 0&&!abort)   {    _fStream.Write(buffer,0,len);    DateTime end = DateTime.Now.ToLocalTime();    info.CostTime = (long)(end - begin).TotalMilliseconds;    info.FileFinished += len;     //類比延時用,實際應用的時候登出他    Thread.Sleep(1000);     HttpContext.Current.Cache[_guid] = info;    abort=((DownloadingFileInfo)HttpContext.Current.Cache[_guid]).Abort;    len = _reader.Read(buffer,0,Buffersize);   }     _reader.Close();   _fStream.Close();   if (abort)   {    if (File.Exists(uploadFilePath + uploadFileName))    {     File.Delete(uploadFilePath + uploadFileName);    }   }  }   }

 

第四步,建立Handler.ashx檔案,用於查看檔案上傳情況。

<%@ WebHandler Language="C#" Class="ProgressHandler.Handler" %>  using System.Web; using System.Xml.Linq;  namespace ProgressHandler {  public class Handler : IHttpHandler  {   /// <summary>   /// 獲得上傳檔案的進度   /// </summary>   /// <param name="context">當前請求實體</param>   /// <creattime>2015-06-28</creattime>   /// <author>FreshMan</author>   public void ProcessRequest(HttpContext context)   {    context.Response.ContentType = "application/xml";    context.Response.Charset = "utf-8";    var guid = context.Request.Form["guid"];    var info = context.Cache[guid] as DownloadingFileInfo;    var doc = new XDocument();    var root = new XElement("root");    if (info != null)    {     var fileName = new XElement("fileName", info.FileName);     var fileFinished = new XElement("fileFinished", info.FileFinished);     var fileSize = new XElement("fileSize", info.FileSize);     var costTime = new XElement("costTime", info.CostTime);     var fileState = new XElement("fileState", info.FileState);     var speed = new XElement("speed", info.Speed);     var percent = new XElement("percent", info.Percent);     var abort = new XElement("abort", false);     root.Add(fileName);     root.Add(fileFinished);     root.Add(fileSize);     root.Add(costTime);     root.Add(fileState);     root.Add(speed);     root.Add(percent);     if (info.Abort)     {      abort.Value = info.Abort.ToString();      context.Cache.Remove(guid);     }     if (info.FileState == "finished")     {      context.Cache.Remove(guid);     }    }    else    {     var none = new XElement("none", "no file");     root.Add(none);    }    doc.Add(root);    context.Response.Write(doc.ToString());    context.Response.End();   }    public bool IsReusable   {    get { return false; }   }  } } 

第五步,建立Abort.ashx檔案,用於取消上傳。

 <%@ WebHandler Language="C#" Class="ProgressHandler.Abort" %> using System.Web; using System.Xml.Linq;  namespace ProgressHandler {  public class Abort : IHttpHandler  {   /// <summary>   /// 取消上傳處理常式   /// </summary>   /// <param name="context">當前請求實體</param>   /// <creattime>2015-06-28</creattime>   /// <author>FreshMan</author>   public void ProcessRequest(HttpContext context)   {    context.Response.ContentType = "application/xml";    context.Response.Charset = "utf-8";    var guid = context.Request.Form["guid"];    var abort = !string.IsNullOrEmpty(context.Request.Form["abort"]);    var info = context.Cache[guid] as DownloadingFileInfo;    if (info != null)    {     info.Abort = abort;     context.Cache[guid] = info;    }    var doc = new XDocument();    var root = new XElement("root");    var flag = new XElement("flag", info == null ? "false" : "true");    root.Add(flag);    doc.Add(root);    context.Response.Write(doc.ToString());    context.Response.End();   }    public bool IsReusable   {    get { return false; }   }   } } 

好了,下面就是編寫javascript指令碼了,我引用了jquery這個架構,另外還用了ui架構。
核心代碼是ajax-progress-upload.js檔案,另外還有一個擷取guid的檔案。

$(document).ready(function () {  var _guid_url = "ProgressHandler/GenerateGuid.ashx";  var _progress_url = "ProgressHandler/Handler.ashx";  var _abort_url = "ProgressHandler/Abort.ashx";  var _target = "#guid";  var _guid = "";  var _cancel = false;  var _timer;  LJQ.setGuid(_target, _guid_url);  $("#upload_panel").draggable({ handle: "#upload_title" });  $("#upload_choose span").hover(function () {   $(this).css({    "color": "#f6af3a",    "border": "1px solid #e78f08"   });  }, function () {   $(this).css({    "color": "#1c94cd",    "border": "1px solid #ddd"   });  });  $("#upload_cancel").click(function () {   $.ajax({    url: _abort_url,    data: { guid: _guid, abort: true },    dataType: "xml",    type: "post",    success: function () {      $("#upload_panel").fadeOut('fast');     $("#back_panel").fadeOut(1000);     window.clearInterval(_timer);    }   });    });  $("#upload_submit").click(function () {   $("#upload_panel").fadeOut('fast');   $("#back_panel").fadeOut("1000");  });  $("form").submit(function () {   _guid = $(_target).val();   if ($("input[name='upload_file']").val() == "") {    alert("未指定上傳檔案!");    return false;   }   $("#upload_progress").css("width", "0%");   $("#finished_percent").html("準備上傳...");   $("#upload_speed").html("");   $("#upload_fileName").html("");   $("#upload_fileSize").html("");   $("#upload_costTime").html("");   var _option = {    url: _progress_url,    data: { guid: _guid },    dataType: "xml",    type: "post",    beforeSend: function () {     $("#back_panel").fadeTo('fast', '0.5');     $("#upload_panel").fadeIn('1000');    },    success: function (response) {      if ($(response).find("root abort").text() == "true") {      $("#upload_panel").fadeOut('fast');      $("#back_panel").fadeOut(1000);      window.clearInterval(_timer);     }      else if ($(response).find("root none").text() == "no file") {      }     else {      var _percent = ($(response).find("root percent").text() * 100);      var _speed = $(response).find("root speed").text();      var _fileSize = $(response).find("root fileSize").text();      var _upload_costTime = $(response).find("root costTime").text();      if (parseInt(_speed) < 1024) {       _speed = LJQ.toFix(_speed) + "Kb";      } else {       _speed = LJQ.toFix(_speed / 1024) + "Mb";      }       if (parseInt(_fileSize) / 1024 < 1024) {       _fileSize = LJQ.toFix(_fileSize / 1024) + "Kb";      } else if (parseInt(_fileSize) / 1024 / 1024 < 1024) {       _fileSize = LJQ.toFix(_fileSize / 1024 / 1024) + "Mb";      } else {       _fileSize = LJQ.toFix(_fileSize / 1024 / 1024 / 1024) + "Gb";      }       if (_upload_costTime < 1000) {       _upload_costTime = _upload_costTime + "毫秒";      } else if (_upload_costTime / 1000 < 60) {       _upload_costTime = parseInt(_upload_costTime / 1000) + "秒" + _upload_costTime % 1000 + "毫秒";      } else {       _upload_costTime = parseInt(_upload_costTime / 1000 / 60) + "分" + parseInt((_upload_costTime % 60000) / 1000) + "秒" + _upload_costTime % 1000 + "毫秒";      }      $("#upload_progress").css("width", parseInt(_percent) + "%");      $("#finished_percent").html("完成百分比:" + LJQ.toFix(_percent) + "%");      $("#upload_speed").html("上傳速度:" + _speed + "/sec");      $("#upload_fileName").html("檔案名稱:" + $(response).find("root fileName").text());      $("#upload_fileSize").html("檔案大小:" + _fileSize);      $("#upload_costTime").html("上傳耗時:" + _upload_costTime);      if (_percent >= 100) {        window.clearInterval(_timer);       $("#finished_percent").html("<span style='color:green;'>檔案上傳完成</span>");      }      if (_cancel) {       window.clearInterval(_timer);      }     }     },    error: function () { }   };    _timer = window.setInterval(function () { $.ajax(_option); }, 1000);   });  }); 

以上為代碼的主要部分。asp.net單檔案帶進度條上傳,不屬於任務控制項,也不是flash類型的上傳,完全是asp.net、js、css實現上傳。源碼為開發測試版,需要使用的親需要注意修改設定檔。

項目源碼下載請點擊這裡:http://xiazai.jb51.net/201509/yuanma/asp_net_progressbar(jb51.net).rar

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.