<div id="FormContent"><form id="FormUpload"enctype="multipart/form-data" method="post"><span class="btn btn-success fileinput-button"><i class="glyphicon glyphicon-plus"></i><span>Add files...</span><input type="file"name="UploadedFile" id="UploadedFile" /></span><button class="btn btn-primary start"type="button" id="Submit_btn"><i class="glyphicon glyphicon-upload"></i><span>Start upload</span></button><button class="btn btn-warning cancel"type="button" id="Cancel_btn"><i class="glyphicon glyphicon-ban-circle"></i><span>close</span></button></form><div class="progress CustomProgress"><div id="FileProgress"class="progress-bar" role="progressbar"aria-valuenow="" aria-valuemin=""aria-valuemax="" style="width %;"><span></span></div></div><div class="InfoContainer"><div id="Imagecontainer"></div><div id="FileName" class="info"></div><div id="FileType" class="info"></div><div id="FileSize" class="info"></div></div></div>在Onchange 事件中添加输入文件元素,并在JS方法SingleFileSelected使用,因此在用户选择和修改文件时都会调用此方法。在该方法中,我们将选择输入文件元素和访问FileList的文件对象,选择第一个文件files[0],因此我们可以得到文件名,文件类型等信息。
function singleFileSelected(evt) { //var selectedFile = evt.target.files can use this or select input file element//and access it"s files object var selectedFile = ($("#UploadedFile"))[].files[];//FileControl.files[]; if (selectedFile) { var FileSize = ; var imageType = /image.*/; if (selectedFile.size > ) { FileSize = Math.round(selectedFile.size * / ) / + " MB";}else if (selectedFile.size > ) {FileSize = Math.round(selectedFile.size * / ) / + " KB";}else {FileSize = selectedFile.size + " Bytes";}// here we will add the code of thumbnail preview of upload images$("#FileName").text("Name " + selectedFile.name);$("#FileType").text("type " + selectedFile.type);$("#FileSize").text("Size " + FileSize);}}可以通过File reader对象从内存读取上传文件内容。reader 对象提供很多事件,onload,onError以及四种读取数据的函数readAsBinaryString(), readAsText(),readAsArrayBuffer(), readAsDataURL(),result属性表示文件内容。该属性只有当读操作执行完成后才有效,数据格式根据调用的初始化读操作制定的。
if (selectedFile.type.match(imageType)) {var reader = new FileReader();reader.onload = function (e) {$("#Imagecontainer").empty();var dataURL = reader.result;var img = new Image()img.src = dataURL;img.className = "thumb";$("#Imagecontainer").append(img);};reader.readAsDataURL(selectedFile);}到现在为止,就可看到下图:
现在需要将已上传的文件发送到服务器,因此添加Onclick事件,并在JS uploadFile()方法中调用,代码如下:
function UploadFile() { //we can create form by passing the form to Constructor of formData object //or creating it manually using append function//but please note file name should be same like the action Parameter //var dataString = new FormData(); //dataString.append("UploadedFile", selectedFile);var form = $("#FormUpload")[]; var dataString = new FormData(form);$.ajax({url "/Uploader/Upload", //Server script to process datatype "POST",xhr function () { // Custom XMLHttpRequestvar myXhr = $.ajaxSettings.xhr();if (myXhr.upload) { // Check if upload property exists//myXhr.upload.onprogress = progressHandlingFunctionmyXhr.upload.addEventListener("progress", progressHandlingFunction, false); // For handling the progress of the upload}return myXhr;},//Ajax eventssuccess successHandler,error errorHandler,completecompleteHandler,// Form datadata dataString,//Options to tell jQuery not to process data or worry about content-type.cache false,contentType false,processData false});}在该方法中,发送表单,使用Form 数据对象来序列化文件值,我们可以手动创建formdata数据的实例化,通过调用append()方法将域值挂起,或是通过检索HTML 表单的FormData对象。
function progressHandlingFunction(e) { if (e.lengthComputable) { var percentComplete = Math.round(e.loaded * / e.total); $("#FileProgress").css("width",percentComplete + "%").attr("aria-valuenow", percentComplete); $("#FileProgress span").text(percentComplete + "%"); } else { $("#FileProgress span").text("unable to compute");}}现在已经实现了基本的发送数据及提供进度条的功能,接下来需要实现服务器端的代码处理,使用upload action方法和uplpader controller 。
public JsonResult Upload(HttpPostedFileBase uploadedFile) { if (uploadedFile != null && uploadedFile.ContentLength > ) { byte[] FileByteArray = new byte[uploadedFile.ContentLength]; uploadedFile.InputStream.Read(FileByteArray, , uploadedFile.ContentLength); Attachment newAttchment = new Attachment();newAttchment.FileName = uploadedFile.FileName;newAttchment.FileType = uploadedFile.ContentType;newAttchment.FileContent = FileByteArray;OperationResult operationResult = attachmentManager.SaveAttachment(newAttchment);if (operationResult.Success){string HTMLString = CaptureHelper.RenderViewToString("_AttachmentItem", newAttchment, this.ControllerContext);return Json(new{statusCode = ,status = operationResult.Message,NewRow = HTMLString}, JsonRequestBehavior.AllowGet);}else{return Json(new{statusCode = ,status = operationResult.Message,file = uploadedFile.FileName}, JsonRequestBehavior.AllowGet);}}return Json(new{statusCode = ,status = "Bad Request! Upload Failed",file = string.Empty}, JsonRequestBehavior.AllowGet);}能否通过拖拽操作实现多个文件上传的功能?
<div id="drop_zone">Drop images Here</div>在JS方法MultiplefileSelected中添加onChange事件,与之前SingleFileSelected的写法类似,不同的是需要将所有的文件列出,并允许拖拽文件。代码如下:
function MultiplefileSelected(evt) { evt.stopPropagation(); evt.preventDefault(); $("#drop_zone").removeClass("hover"); selectedFiles = evt.target.files || evt.dataTransfer.files; if (selectedFiles) { $("#Files").empty(); for (var i = ; i < selectedFiles.length; i++) { DataURLFileReader.read(selectedFiles[i], function (err, fileInfo) {if (err != null) {var RowInfo = "<div id="File_" + i + "" class="info"><div class="InfoContainer">" +"<div class="Error">" + err + "</div>" + "<div data-name="FileName"class="info">" + fileInfo.name + "</div>" + "<div data-type="FileType"class="info">" + fileInfo.type + "</div>" + "<div data-size="FileSize"class="info">" + fileInfo.size() +"</div></div><hr/></div>";$("#Files").append(RowInfo);}else {var image = "<img src="" + fileInfo.fileContent + "" class="thumb" title="" + fileInfo.name + "" />";var RowInfo = "<div id="File_" + i + "" class="info"><div class="InfoContainer">" + "<div data_img="Imagecontainer">" +image + "</div>" + "<div data-name="FileName"class="info">" + fileInfo.name + "</div>" + "<div data-type="FileType"class="info">" + fileInfo.type + "</div>" + "<div data-size="FileSize"class="info">" + fileInfo.size() +"</div></div><hr/></div>";$("#Files").append(RowInfo);}});}}}在该方法中,将选择和拖拽文件操作的变量设置为全局变量selectedFiles,然后扫描 selectedfiles中的每个文件,将从 DataURLreader对象中调用Read 方法读取文件。
var DataURLFileReader = { read function (file, callback) { var reader = new FileReader(); var fileInfo = { name file.name, type file.type, fileContent null, size function () { var FileSize = ;if (file.size > ) {FileSize = Math.round(file.size * / ) / + " MB";}else if (file.size > ) {FileSize = Math.round(file.size * / ) / + " KB";}else {FileSize = file.size + " bytes";}return FileSize;}};if (!file.type.match("image.*")) {callback("file type not allowed", fileInfo);return;}reader.onload = function () {fileInfo.fileContent = reader.result;callback(null, fileInfo);};reader.onerror = function () {callback(reader.error, fileInfo);};reader.readAsDataURL(file);}};使用拖拽操作选择
function handleDragOver(evt) { evt.preventDefault(); evt.dataTransfer.effectAllowed = "copy"; evt.dataTransfer.dropEffect = "copy"; }接着在MultiplefileSelected中添加drop事件来处理文件drop操作。
function UploadMultipleFiles() { // here we will create FormData manually to prevent sending mon image files var dataString = new FormData(); //var files = document.getElementById("UploadedFiles").files; for (var i = ; i < selectedFiles.length; i++) { if (!selectedFiles[i].type.match("image.*")) { continue; }}// AJAX Request code here}接下来添加服务器端处理代码,与上文添加的代码类似,需要做的就是接受一系列的文件列表,如下:
<system.webServer><security> <requestFiltering><requestLimits maxAllowedContentLength="" /> </requestFiltering></security> </system.webServer> <httpRuntime targetFramework="." maxRequestLength=""/>到这里所有的功能就可以实现了,而且最大可上传2GB的文件。