50010702506256
ASP.NET MVC + WebUploader+BootStrap实现文件上传进度条显示
分类:
.NET MVC
引入需要的资源文件:
<script src="~/Content/jquery-1.9.1.min.js"></script> <link href="~/Content/webuploader/webuploader.css" rel="stylesheet" /> <script src="~/Content/webuploader/webuploader.min.js"></script>
html:
<div id="uploader" class="wu-example"> <!--用来存放文件信息--> <ul id="thelist" class="list-group"></ul> <div class="uploader-list"></div> <div class="btns"> <div id="picker" style="float: left;">选择文件</div> <input id="ctlBtn" type="button" value="开始上传" class="btn btn-default" style="width: 78px; height: 37px; margin-left: 10px;" /> </div> </div> <!-- 自己简单弄一个进度条--> <div id="progressdiv" style="width: 500px; background: #f5f5f5; height: 34px; margin-top: 50px;"> <div class="progress-bar" style="height: 34px; background: #53CED9; width: 0px"> </div> </div>
js:
<script>
var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../../";
var GUID = WebUploader.Base.guid();//一个GUID
$(function () {
var $ = jQuery;
var $list = $('#thelist');
var uploader = WebUploader.create({
// 选完文件后,是否自动上传。
auto: false,
// swf文件路径
swf: applicationPath + '../Content/webuploader/Uploader.swf',
// 文件接收服务端。
//server: applicationPath + '/home/Upload',
server: '/home/Upload',
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: '#picker',
// 只允许选择office文件。
accept: {
title: 'Office',
extensions: "pdf,doc,ppt,pptx,xls,xlsx,docx,rar,zip,7z,tar.gz,war,jar,txt,chm,pdr,azw,prc,mbp,tan,tpz,epub,mobi,rp",
mimeTypes: ".pdf,.doc,.ppt,.pptx,.xls,.xlsx,.docx,.rar,.zip,.7z,.tar.gz,.war,.jar,.txt,.chm,.pdr,.azw,.prc,.mbp,.tan,.tpz,.epub,.mobi,.rp"
},
// 只允许选择视频文件。
//accept: {
// title: 'Video', 文字描述
// extensions: 'mp4,ogv,webm', 允许的文件后缀,不带点,多个用逗号分割。
// mimeTypes: 'video/*', 多个用逗号分割。
// },
fileNumLimit: 10, //最大上传数量为10
fileSingleSizeLimit: 50 * 1024 * 1024, //限制上传单个文件大小20M (上传文件过大居然没有提示,我说什么效果都没有)
fileSizeLimit: 200 * 1024 * 1024, //限制上传所有文件大小200M
//上传文件数量限制
fileNumLimit: 1,
// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: false
});
// 当有文件被添加进队列的时候
uploader.on('fileQueued', function (file) {
$list.append('<div id="' + file.id + '" class="item">' +
'<h4 class="info">' + file.name + '</h4>' +
'<p class="state">等待上传...</p>' +
'</div>');
var name = file.name; //文件名
var type = fileType(file.name); //文件类型,获取的是文件的后缀
var volume = bytesToSize(file.size); //文件大小格式化
var oTr = $("<tr></tr>");
var str = '<td><cite title="' + name + '">' + name + '</cite></td>';
str += '<td>' + type + '</td>';
str += '<td>' + volume + '</td>';
str += '<td id="jintutiao">';
str += '<span id="baifenbi"></span>0%';
str += '</td>';
str += '<td id="uploding">等待上传</td>';
$(".fileList").html(str)
});
var aa = 1;
// 文件上传过程中创建进度条实时显示。
uploader.on('uploadProgress', function (file, percentage) {
console.log("上传中");
//计算进度条应该显示的宽度(进度条div的宽度*百分比即可)
var precentWidth = parseInt($("#progressdiv").width()) * percentage;
console.log(percentage);
console.log("计算出来的宽度:" + precentWidth);
$(".progress-bar").width(precentWidth)
// $percent.css('width', percentage * 100 + '%');
// console.log(percentage * 100 + '%');
if (percentage == 1) {
aa++;
}
if (aa <= 2) {
var shuzi = percentage * 100;
$("#baifenbi").html(shuzi.toFixed(2));
}
});
// 文件上传成功,给item添加成功class, 用样式标记上传成功。
uploader.on('uploadSuccess', function (file, response) {
console.log("已上传");
$('#' + file.id).find('p.state').text('已上传');
//上传成功后,到Merge控制器
$.post('/#/Merge', { guid: GUID, fileName: file.name }, function (data) {
$("#uploader .state").html("上传成功...");
$("#uploding").html("上传成功");
});
});
/**
* 验证文件格式以及文件大小
*/
uploader.on("error", function (type) {
if (type == "Q_TYPE_DENIED") {
alert("请上传JPG、PNG、GIF、BMP格式文件");
} else if (type == "Q_EXCEED_SIZE_LIMIT") {
alert("文件大小不能超过50M");
} else {
alert("上传出错!请检查后重新上传!错误代码" + type);
}
});
// 完成上传完了,成功或者失败,先删除进度条。
uploader.on('uploadComplete', function (file) {
console.log("uploadComplete");
$('#' + file.id).find('.progress').fadeOut();
});
//所有文件上传完毕
uploader.on("uploadFinished", function () {
//提交表单
console.log("提交表单");
});
//开始上传
$("#ctlBtn").click(function () {
uploader.upload();
});
});
//字节大小转换,参数为b
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'G'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};
//通过文件名,返回文件的后缀名
function fileType(name) {
var nameArr = name.split(".");
return nameArr[nameArr.length - 1].toLowerCase();
}
</script>后台:
public ActionResult Upload()
{
string fileName = Request["name"];
//string fileRelName = fileName.Substring(0, fileName.LastIndexOf('.'));//设置临时存放文件夹名称
//int index = Convert.ToInt32(Request["chunk"]);//当前分块序号
//var guid = Request["guid"];//前端传来的GUID号
var data = Request.Files["file"];//表单中取得分块文件
string extension = data.FileName.Substring(data.FileName.LastIndexOf(".") + 1,
(data.FileName.Length - data.FileName.LastIndexOf(".") - 1));//获取文件扩展名
if (data != null)//为null可能是暂停的那一瞬间
{
data.SaveAs(Server.MapPath("~/Upload") + "/" + fileName);
}
return Json(new { erron = 0 });//Demo,随便返回了个值,请勿参考
}这里要注意asp.net mvc中上传文件大小的限制,如果超过了就会报错,我们可以在web.config中配置
1:system.webServer中加入或修改配置
<security> <requestFiltering> <requestLimits maxAllowedContentLength="2147483647" ></requestLimits> </requestFiltering> </security>
2:system.web中加入或修改配置
<!--最大请求长度,单位为kb--> <httpRuntime targetFramework="4.5" maxRequestLength="100000" />
来看一个简单的效果:

上传文件的时候传递其他参数的问题,我们一般不是仅仅就只传递一个问题
方法1:在添加文件的时候就直接先传递了,然后在传递其他参数(表单提交或者ajax看你喽)
监听事件:当有文件被添加进队列的时候,直接提交文件上传
// 当有文件被添加进队列的时候
uploader.on('fileQueued', function (file) {
//选择文件的时候直接上传
uploader.upload();
});方法2:监听文件发送之前的事件 , 文件和参数一起传递
//监听文件发送之前的事件
uploader.on('uploadBeforeSend', function (block, data) {
// file为分块对应的file对象。
var file = block.file;
// 修改data可以控制发送哪些携带数据。
data.username = "xj";
data.number = "a";
});这里参数的传递可以直接表单序列化成功json字符串来传递还方便快捷一点,不用一个一个的取出来赋值
方法3:监听上传完成事件uploadFinished,文件传递成功后在提交其他参数
//所有文件上传完毕
uploader.on("uploadFinished", function () {
//提交表单
console.log("提交表单");
});万事开头难,demo就是这样了,大家实际用的时候可以随意的自由发挥

webuploader 接收后台返回值
我们不仅仅是需要前台验证后台也需要验证,所以真正的成功与否应该还需要根据后台的信息来进行验证
接收后台验证其实就是监听:uploadSuccess事件即可
uploader.on('uploadSuccess', function (file, response) {
//其他操作
//console.log(response);
if (response.Code == 500) {
alert(response.Message);
}
});其中的response就是后台的返回值,一般都是json所以可以直接点出来判断
tip:uploadSuccess事件比uploadComplete早一点
下面说一下博客项目中资源上传界面的处理
博客项目后台目前使用的是bootstrap,实际项目中运行肯定界面这些要做好看一点嘛

先看看效果图
上传文件的界面如下:

上传中的时候就显示出来进度条:

其实就是上传前显示点击上传文件,点击提交后就显示进度条而已。
就是一个小技巧在进度条div里边在加一个div来显示文字,上传前就显示出来,上传中就隐藏掉只显示进度条了
<div class="progress progress-striped" style="height: 34px; margin-bottom: 5px; text-align: center"> <!-- 放个span来显示文字--> <span style="display: inline-block;cursor:pointer; margin-top: 7px; display:block;"><i class="fa fa-folder"></i>请选择文件</span> <!-- 实际进度条--> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%"> </div> </div>
当然也可以不隐藏,上传中就显示文件的名字也是可以的,这样的话就会写一点样式来让里边的文字悬浮不影响进度条的显示
bootstrap进度条显示百分比
把span里边的样式删除掉即可

去掉这个sr-only样式后就可以显示了

demo下载地址:https://download.tnblog.net/resource/index/42AE33C8112246B79F4444B5596E94DA
.net core版本下载地址:https://download.tnblog.net/resource/index/d46969b5a1c840878c06485bff8173b0
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)