最近做一个项目,需要用到多文件的上传。其实使用普通的file也可以实现,未免就是样式太难看了。于是在网上搜索拥有此功能的上传插件,发现jquery.fileupload.js和dropzone.js是不同的选择,相比之下,个人觉得drop.js使用起来更为简单一点,于是这篇文章将记录自己的一点心得,备以后查看,也为需要的朋友提供一个参考。
dropzone有两种方式实现文件的上传,一种使用form,另一种就是div,由于我的文件上传区在一个form表单中,所以使用第一种form的话,form中套form就会引起错误,所以我使用了第二种div的方式,本文也会主要介绍这种方式。
咱们都知道,使用一个插件之前,得引入它的样式和js文件。所以首先咱得先引入相关文件,如下:
Dropzone 是不依赖 jQuery 框架的,所以对于dropzone的初始化操作都分为jquery和非jquery两种,相信当家都习惯用jquery了吧,那咱们就以jquery版本来说,那么您就需要引入jquery了,如果是在需要非jquery操作,那么这里有一个参考的api,挺不错的 。dropzone.js中文文档
A、form方式
这种方式比较简单,Dropzone将查找所有的 class 属性中包含 dropzone 的表单元素,的表单元素,自动地把自己加入到表单元素上,并且拖拽进的这些上传文件将被发送到
action
这个特殊的参数。所以在此action是不能缺少的,要不文件就不知道提交到哪进行处理了。 这些上传文件将被正常处理像下面这样的HTML代码:
B、div方式
对,需要的代码就这么点。下面进行dropzone的初始化。
在这次的项目中,是在点击后提交文件,不是选中后上传,选中上传更简单点额。如下初始化代码
//div做上传区域时使用的配置
Dropzone.autoDiscover = false;// 禁止对所有元素的自动查找,由于Dropzone会自动查找class为dropzone的元素,自动查找后再在这里进行初始化,有时候(并不是都这样)会导致重复初始化的错误,所以在此加上这段代码避免这样的错误。
$("#myDropzone").dropzone(
//项目使用.net,所以此处的action就这样了。该参数必须指定。
url: '@Url.Action("fileupload", "FileUpload")' + "/" + para,
//改变文件框中的文字提示
dictDefaultMessage: ' 拖动文件至该处(或点击此处)
',
//方式指定
method: 'post',
filesizeBase: 102400000,//这个选项将设置在计算文件大小时使用 1000 还是使用 1024作为基本单位
//dropzone同时上传的文件不能超过6个,所以parallelUploads的设置就不能大于6,大于6后就会出现“超过最大长度” //错误,导致上传失败
parallelUploads: 5,//有多少文件将上载到并行处理,默认2(一次最多上传不能超过6个,小于等于6个的传完后,再上传 //第二批的文件)
maxFilesize: 3072,//以MB为单位[上传文件的大小限制]
autoProcessQueue: false,//关闭自动上传功能,默认会true会自动上传,也就是添加一张图片向服务器发送一次请求
addRemoveLinks:true,//在每个预览文件下面添加一个remove[删除]或者cancel[取消](如果文件已经上传)上传文件的链 接
uploadMultiple: true,//允许上传多文件
dictCancelUpload: '取消',
dictRemoveFile: '删除',
dictFallbackMessage: '不好意思,您的浏览器不支持!',//如果浏览器不支持,默认消息将被替换为这个文本。默认为 “Your browser does not support drag'n'drop file uploads.”。
dictInvalidFileType: '该文件不允许上传',//如果文件类型不匹配时显示的错误消息。
dictResponseError:'上传失败,请稍后重试',//如果服务器响应是无效的时候显示的错误消息。 {{statusCode}} ` 将被 替换为服务器端返回的状态码。
//函数绑定
init: function () {
var submitButton = $("#saveForm")
myDropzone = this; // closure
//为上传按钮添加点击事件
submitButton.on("click", function () {
//此处可以动态设置url,为了向文件上传的后台提供项目对应的id
myDropzone.options.url = '@Url.Action("fileupload", "FileUpload")' + "/" +para;
//手动上传所有图片
//saveQuestion是我的一个保存表单其他数据的方法,保存成功后,返回true
if (saveQuestion()) {
//判断上传的文件不为空时,(保证没有选择文件的时候不进行上传操作)
if (myDropzone.getAcceptedFiles().length != 0) {
//如果你设置了选项 autoProcessQueue 为 true, 然后队列就会被立即处理, 在
//文件拖放到zone或者上传完成后, 调用.processQueue() 来检查当前有多少文件
//正在被上传,如果它的值小于options.parallelUploads的设置值时,就会调用
//.processFile(file)上传文件
// 如果你设置 autoProcessQueue为false, 那么 .processQueue() 方法是不会
//被隐式调用的. 这意味着你必须在你想要上传队列中的所有文件时,自己去调用这
//个方法(引用自:
//http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/#installation)
//手动指定
myDropzone.processQueue();
}
else
{
//操作
}
}
});
//当添加图片后的事件
//this.on("addedfile", function (file) {
// 代码
//});
//当上传完成后的事件,接受的数据为JSON格式
//如果是单文件的上传,该文件上传完成之后返回关于此文件的一些信息
//多文件同时上传的时候,只返回的是最后上传的那个文件的信息
this.on("complete", function (data) {
//代码
});
//删除图片的事件,file包含文件的一些信息
this.on("removedfile", function (file) {
//这是点击删除按钮(remove file)的删除事件,但是这里的删除只是将文件从这个显示区移除而已,
//并没有删除文件,如果想自己删除存储了的文件或者其他的操作,请重新编写。 例如:
//上传成功后的删除,点击删除同时删除本地图片与数据库数据
var xhr = JSON.parse(file.xhr.response);
var filenewname = "";
for (var i = 0; i < xhr.fileinfolist.length; i++) {
if (xhr.fileinfolist[i].fileName == file.name) {
filenewname = xhr.fileinfolist[i].fileNewName;
}
}
var filepath = xhr.fileRoot + "\\" + filenewname;
//以上获取上传成功后的路径,然后在你自己的删除事件中进行处理
delFile(filepath);
});
//上传成功后的事件
//每上传成功一个文件,返回一对关于此文件的file和res,多文件一起上传时将返回几对这样的数 据
//这里的res就是后台处理文件的方法返回的json数据。至于返回怎样的json数据,完全是由自己自 定义的
this.on("success", function (file, res) {
//代码
});
}
}
.net MVC后台文件上传代码:
public ActionResult fileupload()
{
bool isSavedSuccessfully = true;
int count = 0;
string msg = "";
string fileName = "";
string fileExtension = "";
string filePath = "";
string fileNewName = "";
string fileRoot = "";
List fileinfolist = new List();
//项目的ID(就是刚才action后面的参数)
int projectId = Convert.ToInt32(RouteData.Values["id"]);
try
{
//指定你的文件上传位置
string directoryPath = Server.MapPath("~/File/file");
//如果路径不存在将创建
if (!Directory.Exists(directoryPath))
Directory.CreateDirectory(directoryPath);
//多文件上传循环取出数据
foreach (string f in Request.Files)
{
HttpPostedFileBase file = Request.Files[f];
if (file != null && file.ContentLength > 0)
{
fileName = file.FileName;
fileExtension = Path.GetExtension(fileName);
fileNewName = Guid.NewGuid().ToString() + fileExtension;
fileRoot = Path.Combine(directoryPath);
filePath = Path.Combine(directoryPath, fileNewName);
//保存文件
file.SaveAs(filePath);
string tmpRootDir = Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());//获取程序根目录
string RelativePath = filePath.Replace(tmpRootDir, ""); //转换成相对路径(数据库中存储的路径)
RelativePath = "/" + RelativePath.Replace(@"\", @"/");
//更多的文件操作
........
count++;
}
}
saveFile(fileinfolist);
}
catch (Exception ex)
{
msg = ex.Message;
isSavedSuccessfully = false;
//程序出错,删除文件
foreach (var item in fileinfolist)
{
string tmpRootDir = Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());
string filepath = tmpRootDir.Substring(0, tmpRootDir.Length - 1) + item.filePath.Replace(@"/", @"\");
System.IO.File.Delete(filepath);
}
}
//这里返回的json就是事件绑定success中的res参数。
return Json(new
{
Result = isSavedSuccessfully,
Count = count,
Message = msg,
fileinfolist = fileinfolist,
fileRoot = fileRoot
});
}
以上基本就是使用dropzone上传文件的一些总结了,不清楚查看文档 dropzone中文文档,下面顺便将.net mvc文件的下载等常用操作记录下:
删除本地的文件(用来dropzone上传成功后的删除额,即romovedfile中的文件上传后的删除可以用到),如下,c此处的filepath是数据库中的相对路径,也就是上面程序处理后的RelativePath,如果此处已经是绝对路径,就不用这么处理了,直接最后一行代码删除就ok了。
string tmpRootDir = Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());
string filepath = tmpRootDir.Substring(0, tmpRootDir.Length - 1) + FilePath.Replace(@"/", @"\");
System.IO.File.Delete(filepath);
文件下载:
后台:
int id = Convert.ToInt32(RouteData.Values["id"]);
var solution = getSolutionByid(id);//该方法通过id获取文件存储在数据库中的信息
string filePath = solution.FilePath;//相对路径
var fullpathname = Server.MapPath(filePath);//转换为文件的绝对路径
return File(new FileStream(fullpathname, FileMode.Open), "application/octet-stream", Server.UrlEncode(solution.FileName));
前台:
window.open('@Url.Action("downloadSolutionAttachment", "SWmaintenance")' + "/" + id);