asp.net单文件带进度条上传的解决方案_实用技巧

最近做项目中遇到很多问题,比如带进度条的文件上传,看了网上很多资料还没找到真正意义上的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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索asp.net单文件上传
,以便于您获取更多的相关知识。

时间: 2024-10-29 05:43:39

asp.net单文件带进度条上传的解决方案_实用技巧的相关文章

ASP.NET对大文件上传的解决方案_实用技巧

首先,我们需要下载这个名为 RanUpLoad 的组件. 下载完成之后,两个 dll 文件添加到项目的引用中区,xml 文件也要复制在项目中的 bin 文件夹下,也就是最后三个文件都要存在于 bin 文件夹中. 接着,上传控件还是用 ASP.NET 中自带的 FileUpload 控件,需要添加的就是在 FileUpload 控件旁边加入标签: <radU:RadProgressManager ID="Radprogressmanager1" Width="100%&q

ASP.NET设计FTP文件上传的解决方案_实用技巧

如果要用ASP来作一个FTP文件上传的页面,我想很多人立刻就会想到要用第三方开发的组件,利用第三方的组件,虽然开发起来相对比较容易.但一般来说,免费下载的第三方的组件都有某些方面的功能限制,若要购买正版的第三方组件,对于国内的用户,花销也是一个不小的数字,就是能够承担的起,烦杂的手续也使很多人望而却步.虽然微软公司在本身的视窗系统里面也提供了一个可以用来上传文件的组件--Posting Acceptor.但用过这个组件的朋友们都有一种普遍的感觉,就是实在不好用. 现在好了,自从微软公司推出了.N

PHP+Ajax异步带进度条上传文件实例_php实例

最近项目中要做一个带进度条的上传文件的功能,学习了Ajax,使用起来比较方便,将几个方法实现就行. 前端引入文件 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min

PHP+Ajax异步带进度条上传文件实例

最近项目中要做一个带进度条的上传文件的功能,学习了Ajax,使用起来比较方便,将几个方法实现就行. 前端引入文件 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min

.net 带进度条上传控件怎么实现?

问题描述 RT....在网上找了好多如swfupload,FancyUpload之类的都没法实现我的需求.需要在选择文件后获取到文件在客户端的路径. 解决方案 解决方案二:或者谁知道上面说的控件怎么能获取到文件路径.解决方案三:ActiveX解决方案四:你可以试试百度的webuploader,不过你获取客户端路径有什么用??解决方案五:引用楼主zy843043569的回复: RT....在网上找了好多如swfupload,FancyUpload之类的都没法实现我的需求.需要在选择文件后获取到文件

asp.net文件上传示例分享_实用技巧

方法一:用Web控件FileUpload,上传到网站根目录. Test.aspx关键代码: 复制代码 代码如下: <form id="form1" runat="server"><asp:FileUpload ID="FileUpload1" runat="server" /><asp:Button ID="Button1" runat="server" T

asp.net 文件上传实例汇总_实用技巧

ASP.NET依托.net framework类库,封装了大量的功能,使得上传文件非常简单,主要有以下三种基本方法. 方法一:用Web控件FileUpload,上传到网站根目录. Test.aspx关键代码: 复制代码 代码如下:      <form id="form1" runat="server">     <asp:FileUpload ID="FileUpload1" runat="server"

asp.net下大文件上传知识整理_实用技巧

最近做在做ePartner项目,涉及到文件上传的问题. 以前也做过文件上传,但都是些小文件,不超过2M. 这次要求上传100M以上的东西. 没办法找来资料研究了一下.基于WEB的文件上传可以使用FTP和HTTP两种协议,用FTP的话虽然传输稳定,但安全性是个严重的问题,而且FTP服务器读用户库获取权限,这样对于用户使用来说还是不太方便. 剩下只有HTTP.在HTTP中有3种方式,PUT.WEBDAV.RFC1867,前2种方法不适合大文件上传,目前我们使用的web上传都是基于RFC1867标准的

asp将本地的文件上传到服务器_实用技巧

今天我们讲解如何利用asp的上传功能将本地的文件上传到服务器上. 最简系统包括下面三个文件: upload.htm                         --上传口文件,选择本地文件 uploadimg.asp                  --上传程序控制文件 upload_5xsoft.inc            --无组件上传类,此文件初学者不用学习,只要会用就可以了 upload.htm内容----上传口文件,选择本地文件 <html> <head> <