ajax 上传文件_.NET Core+WebUploader实现大文件分片上传

(给DotNet加星标,提升.Net技能)

转自:踏平扶桑 cnblogs.com/wdw984/p/11725118.html

项目要求通过网站上传大文件,比如视频文件,通过摸索实现了文件分片来上传,然后后台进行合并。

使用了开源的前台上传插件WebUploader

(http://fex.baidu.com/webuploader/)

WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。

在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。

采用大文件分片并发上传,极大的提高了文件上传效率。

直接上代码,前台cshtml

@{
Layout = null;
}
<html><head><meta name="viewport" content="width=device-width" /><link href="~/js/webuploader/webuploader.css" rel="stylesheet" /><link href="~/js/bootstrap.min.css" rel="stylesheet" /><script src="~/js/jquery.min.js">script><script src="~/js/webuploader/webuploader.js">script><title>Uploadtitle><script>
jQuery(function () {var $ = jQuery,
$list = $('#thelist'),
$btn = $('#ctlBtn'),
state = 'pending',
fileMd5,
flag = true,
dataState,
fm = [],
fnum,
Token,
uploader;var FileExt = ["mpg", "mpeg", "mp4", "avi"];
Token = '@ViewBag.Token';if (Token == '' || Token== 'undefined')
{
$("#uploader").hide();
alert("登录超时,请重新登录。");
}//监听分块上传过程中的三个时间点
WebUploader.Uploader.register({"before-send-file": "beforeSendFile","before-send": "beforeSend","after-send-file": "afterSendFile",
}, {beforeSendFile: function (file) {var startTime = new Date(file.lastModifiedDate);
fileName = file.name;var deferred = WebUploader.Deferred();
(new WebUploader.Uploader()).md5File(file, 0, 10 * 1024 * 1024)
.progress(function (percentage) {console.log("正在读取文件");
})
.then(function (val) {
fileMd5 = val;
fm.push(fileMd5);
deferred.resolve();
});return deferred.promise();
},//时间点2:如果有分块上传,则每个分块上传之前调用此函数
beforeSend: function (block) {var deferred = WebUploader.Deferred();//上传前ajax检测一下此文件块是否已经上传this.owner.options.formData.fileMd5 = fileMd5;this.owner.options.formData.chunk = block.chunk;
deferred.resolve();return deferred.promise();
},//时间点3:所有分块上传成功后调用此函数
afterSendFile: function (file) {var deferred = $.Deferred();
$('#' + file.id).find('p.state').text('执行最后一步');console.log(file);console.log(file.guid);
$.ajax({type: "POST",url: "/api/v1/Check/FileMerge",data: {guid: file.guid,fileMd5: fm[fnum],fileName: file.name
},cache: false,async: false,success: function (response) {
fnum++;console.log(response);if (response.success == true) {
dataState = response;
flag = true;
} else {
flag = false;
}
deferred.resolve();
},error: function () {
fnum++;
dataState = undefined;
flag = false;
deferred.reject();
}
});return deferred.promise();
}
});
uploader = WebUploader.create({resize: false,fileNumLimit: 10,swf: '/js/Uploader.swf',server: '/api/v1/Check/FileSave',pick: '#picker',chunked: true,chunkSize: 10 * 1024 * 1024,chunkRetry: 5//, formData: {// guid: GUID//}
});
uploader.on('beforeFileQueued', function (file) {var isAdd = false;for (var i = 0; i < FileExt.length; i++) {if (file.ext == FileExt[i]) {
file.guid = WebUploader.Base.guid();
isAdd = true;break;
}
}return isAdd;
});
uploader.on('uploadBeforeSend', function (object, data, headers) {//console.log(object);
headers.Authorization =Token;
data.guid = object.file.guid;
});// 当有文件添加进来的时候
uploader.on('fileQueued', function (file) {
$list.append('
'" >' +'
'
+ file.name + '' +''" value="' + file.guid + '" />' +'

等待上传...

' +'
');
});// 文件上传过程中创建进度条实时显示。
uploader.on('uploadProgress', function (file, percentage) {var $li = $('#' + file.id),
$percent = $li.find('.progress .progress-bar');// 避免重复创建if (!$percent.length) {
$percent = $('
' +'
' +'
' +'
').appendTo($li).find('.progress-bar');
}
$li.find('p.state').text('上传中');
$percent.css('width', percentage * 100 + '%');
});
uploader.on('uploadSuccess', function (file) {if (dataState == undefined) {
$('#' + file.id).find('p.state').text('上传失败');
$('#' + file.id).find('button').remove();
$('#' + file.id).find('p.state').before('重新上传');
flag = false;
file.setStatus('error');
}if (dataState.success == true) {
$('#' + file.id).find('p.state').text('已上传');
$('#' + file.id).find('button').remove();
} else {
$('#' + file.id).find('p.state').text('上传失败');
flag = false;
}
});
uploader.on('uploadError', function (file) {
$('#' + file.id).find('p.state').text('上传出错');
});
uploader.on('uploadComplete', function (file) {
$('#' + file.id).find('.progress').fadeOut();
});
uploader.on('all', function (type) {if (type === 'startUpload') {
state = 'uploading';
} else if (type === 'stopUpload') {
state = 'paused';
} else if (type === 'uploadFinished') {
state = 'done';
}if (state === 'done') {
$btn.text('继续上传');
} else if (state === 'uploading') {
$btn.text('暂停上传');
} else {
$btn.text('开始上传');
}
});
$btn.on('click', function () {if (state === 'uploading') {
uploader.stop();
} else if (state == 'done') {window.location.reload();
}else {
uploader.upload();
}
});
});script>head><body><div id="uploader" class="wu-example"><span style="color:red">只能上传mpg、mpeg、mp4、avi格式的视频文件span><div id="thelist" class="uploader-list">div><div class="btns"><div id="picker" class="webuploader-container"><div class="webuploader-pick">选择文件div><div style="position: absolute; top: 0px; left: 0px; width: 88px; height: 34px; overflow: hidden; bottom: auto; right: auto;"><input type="file" name="file" class="webuploader-element-invisible" multiple="multiple"><label style="opacity: 0; width: 100%; height: 100%; display: block; cursor: pointer; background: rgb(255, 255, 255);">label>div>div><button id="ctlBtn" class="btn btn-default">开始上传button>div>div>body>html>

后台代码

#region 上传视频
public IActionResult Upload(){
ViewBag.Token = HttpContext.Request.Headers["Authorization"];//获取认证信息,传递给前台,方便Ajax请求时提供
return View();
}
///
/// 上传文件
///
///
[HttpPost]
public async TaskFileSave(){
var date = Request;
var files = Request.Form.Files;
long size = files.Sum(f => f.Length);
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
string fileExt = formFile.FileName.Substring(formFile.FileName.IndexOf('.')); //文件扩展名,不含“.”
long fileSize = formFile.Length; //获得文件大小,以字节为单位
//string newFileName = Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名
string DirPath = Path.Combine(_uploadConfig.TmpPath, Request.Form["guid"]);
if (!Directory.Exists(DirPath))
{
Directory.CreateDirectory(DirPath);
}
var filePath = DirPath + "/" + Request.Form["chunk"] + fileExt;
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
return Ok(new { count = files.Count, size });
}


///
/// 合并请求
///
///
[HttpPost]
public async TaskFileMerge(){
bool ok = false;
string errmsg = "";
try
{
var temporary = Path.Combine(_uploadConfig.TmpPath, Request.Form["guid"]);//临时文件夹
string fileName = Request.Form["fileName"];//文件名
string fileExt = Path.GetExtension(fileName);//获取文件后缀
var files = Directory.GetFiles(temporary);//获得下面的所有文件

var finalFilePath = Path.Combine(_uploadConfig.UpLoadPath + fileName);//最终的文件名
//var fs = new FileStream(finalFilePath, FileMode.Create);
using (var fs = new FileStream(finalFilePath, FileMode.Create))
{
foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))
{
var bytes = System.IO.File.ReadAllBytes(part);
await fs.WriteAsync(bytes, 0, bytes.Length);
bytes = null;
System.IO.File.Delete(part);//删除分块
}
Directory.Delete(temporary);//删除文件夹
ok = true;
}
}
catch (Exception ex)
{
ok = false;
errmsg = ex.Message;
log4net.Error(errmsg);
}
if (ok)
{
return Ok(new { success = true, msg = "" });
}
else
{
return Ok(new { success = false, msg = errmsg }); ;
}
}
#endregion

推荐阅读

(点击标题可跳转阅读)

.NET Core WebAPI 文件分片下载

.NET Core WebAPI 文件分片上传与跨域请求处理

.NET基于WebUploader大文件分片上传、断网续传、秒传

看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能 

b2584be86cffd9b6e49a17177408f037.png

好文章,我在看❤️

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值