asp.net單文件帶進(jìn)度條上傳的解決方案
最近做項(xiàng)目中遇到很多問(wèn)題,比如帶進(jìn)度條的文件上傳,看了網(wǎng)上很多資料還沒找到真正意義上的ASP.NET實(shí)現(xiàn)進(jìn)度條上傳(可能是我沒找到),下面我來(lái)跟大家分享一下我實(shí)現(xiàn)的這個(gè)程序。
首先看下界面效果,當(dāng)然你可以完全修改界面為你自己所用。

先解釋一下這個(gè)程序,該程序采用了jquery框架,實(shí)現(xiàn)了小文件上傳,不超過(guò)80Mb,可以在web.config文件中進(jìn)行相應(yīng)的配置,但是有個(gè)最大值,具體需要查看msdn。開發(fā)環(huán)境采用visual studio 2013 .net framework 4.5,運(yùn)行的時(shí)候大家注意一下是否滿足要求,好了,下面直入正題。
先來(lái)看看實(shí)現(xiàn)原理?;驹恚阂粋€(gè)頁(yè)面進(jìn)行文件上傳,另外一個(gè)頁(yè)面去監(jiān)聽這個(gè)文件上傳了多少。
這里面有兩個(gè)地方需要解釋一下:第一個(gè),如何知道監(jiān)聽的這個(gè)文件就是上傳的這個(gè)文件?實(shí)現(xiàn)機(jī)制很簡(jiǎn)單,就是讓asp.net產(chǎn)生一個(gè)唯一的guid,這個(gè)id序號(hào)是唯一的,通過(guò)ajax取出來(lái)賦值給一個(gè)隱藏字段;第二個(gè),如何獲取guid標(biāo)志的文件信息?通過(guò)asp.net緩存機(jī)制實(shí)現(xiàn),上傳的過(guò)程中,不斷的將上傳信息往緩存里面寫,直到文件上傳完成,而在另外一個(gè)通過(guò)guid獲取緩存的信息,信息包括你想要的信息,比如上傳了多少字節(jié)、消耗了多長(zhǎng)時(shí)間等。好了,要點(diǎn)就解釋到這里,有疑問(wèn)的話給我留言。
下面來(lái)說(shuō)說(shuō)具體的實(shí)現(xiàn):
文件目錄結(jié)構(gòu)如下:

index.htm就是文件上傳頁(yè)面,提交form給UploadHandler目錄下的Default.aspx,以實(shí)現(xiàn)文件上傳。
ProgressHandler目錄下三個(gè)文件為Abort.ashx、GenericGuid.ashx,Handler.ashx功能分別為:根據(jù)Guid取消正在上傳的文件,生成Guid,根據(jù)Guid獲取上傳信息。
第一步:建立index.htm頁(yè)面,這個(gè)上傳頁(yè)面,需要注意的就是需要一個(gè)隱藏的iframe,并且名字為form提交的目標(biāo)。
<!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文件上傳進(jìn)度條示例</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 文件上傳進(jìn)度條示例</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>*本程序適合小文件上傳,不超過(guò)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">正在準(zhǔn)備上傳...</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>
第二步,創(chuàng)建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">當(dāng)前請(qǐng)求實(shí)體</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; }
}
}
}
第三步,創(chuàng)建Default.aspx文件,用于提交表單時(shí)上傳文件。
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()+"http://";
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;
//模擬延時(shí)用,實(shí)際應(yīng)用的時(shí)候注銷他
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);
}
}
}
}
第四步,創(chuàng)建Handler.ashx文件,用于查看文件上傳情況。
<%@ WebHandler Language="C#" Class="ProgressHandler.Handler" %>
using System.Web;
using System.Xml.Linq;
namespace ProgressHandler
{
public class Handler : IHttpHandler
{
/// <summary>
/// 獲得上傳文件的進(jìn)度
/// </summary>
/// <param name="context">當(dāng)前請(qǐng)求實(shí)體</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; }
}
}
}
第五步,創(chuàng)建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">當(dāng)前請(qǐng)求實(shí)體</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這個(gè)框架,另外還用了ui框架。
核心代碼是ajax-progress-upload.js文件,另外還有一個(gè)獲取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("準(zhǔn)備上傳...");
$("#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("上傳耗時(shí):" + _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單文件帶進(jìn)度條上傳,不屬于任務(wù)控件,也不是flash類型的上傳,完全是asp.net、js、css實(shí)現(xiàn)上傳。源碼為開發(fā)測(cè)試版,需要使用的親需要注意修改配置文件。
項(xiàng)目源碼下載請(qǐng)點(diǎn)擊這里:http://xiazai.jb51.net/201509/yuanma/asp_net_progressbar(jb51.net).rar
- Asp.net基于ajax和jquery-ui實(shí)現(xiàn)進(jìn)度條
- ASP.NET實(shí)現(xiàn)進(jìn)度條效果
- asp.net mvc 實(shí)現(xiàn)文件上傳帶進(jìn)度條的思路與方法
- asp.net文件上傳帶進(jìn)度條實(shí)現(xiàn)案例(多種風(fēng)格)
- Asp.Net 無(wú)刷新文件上傳并顯示進(jìn)度條的實(shí)現(xiàn)方法及思路
- asp.net 生成靜態(tài)頁(yè)時(shí)的進(jìn)度條顯示
- 利用Asp.Net回調(diào)機(jī)制實(shí)現(xiàn)進(jìn)度條
- ASP.NET技巧:教你制做Web實(shí)時(shí)進(jìn)度條
- ASP.NET?MVC使用jQuery?ui的progressbar實(shí)現(xiàn)進(jìn)度條
相關(guān)文章
Asp.Mvc 2.0實(shí)現(xiàn)用戶登錄與注銷功能實(shí)例講解(2)
這篇文章主要介紹了Asp.Mvc 2.0實(shí)現(xiàn)用戶登錄與注銷功能,用戶登錄方式都是FORM表單驗(yàn)證方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-08-08
aspx超強(qiáng)木馬查殺與防范(web網(wǎng)馬)
下面代碼是一個(gè)aspx超強(qiáng)木馬,功能很多,大家在服務(wù)器上見到一定要小心2013-12-12
ASP.NET XmlHttp跨域訪問(wèn)實(shí)現(xiàn)代碼
最近項(xiàng)目需要實(shí)現(xiàn)XmlHttp的POST方法到另一服務(wù)器上的頁(yè)面進(jìn)行數(shù)據(jù)的更新,可是IE會(huì)提出“該頁(yè)正在訪問(wèn)其控制范圍之外的信息,是否繼續(xù)?”等警告信息,而在其他瀏覽器上直接禁止掉,GOOGLE一下原來(lái)是XmlHttp的跨域訪問(wèn)問(wèn)題,找了很多資料,說(shuō)是提供很多解決方案,可是都沒有用處。2008-11-11
.NET Framework攔截HTTP請(qǐng)求的實(shí)現(xiàn)
本文主要介紹了.NET Framework攔截HTTP請(qǐng)求的實(shí)現(xiàn),主要用于記錄 HTTP 信息,調(diào)試程序、分析程序性能等方面,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
C#后臺(tái)調(diào)用前臺(tái)javascript的五種方法小結(jié)
于項(xiàng)目需要,用到其他項(xiàng)目組用VC開發(fā)的組件,在web后臺(tái)代碼無(wú)法訪問(wèn)這個(gè)組件,所以只好通過(guò)后臺(tái)調(diào)用前臺(tái)的javascript,從而操作這個(gè)組件。2010-12-12
ASP.NET2.0中數(shù)據(jù)源控件之異步數(shù)據(jù)訪問(wèn)
ASP.NET2.0中數(shù)據(jù)源控件之異步數(shù)據(jù)訪問(wèn)...2006-09-09
批量賬號(hào)的login測(cè)試功能實(shí)現(xiàn)
用WaitiN寫了個(gè)簡(jiǎn)單的login自動(dòng)化測(cè)試,能夠使用少量的代碼實(shí)現(xiàn)批量賬號(hào)的login測(cè)試,需要的朋友可以參考下2012-11-11
asp.net SqlDataReader綁定Repeater
asp.net SqlDataReader綁定Repeater2009-04-04
Asp.Net使用Npoi導(dǎo)入導(dǎo)出Excel的方法
這篇文章主要介紹了Asp.Net使用Npoi導(dǎo)入導(dǎo)出Excel的方法,采用該方法在導(dǎo)出Excel的時(shí)候不需要office組件的支持,而在導(dǎo)入Excel的時(shí)候采用OleDb的方式,需要office組件的支持。是一個(gè)非常實(shí)用的技巧,需要的朋友可以參考下2014-09-09

