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单文件带进度条上传的解决方案 的全部内容, 来源链接: utcz.com/z/320754.html

回到顶部