博主的项目,客户端是APP,考虑到以后也可能会应用到微信端、网站等,图片上传方法就需要兼容多端,并且以目前的设计,不允许非登录用户上传图片,就得在上传时解决附带参数上传图片的问题。
先来看看后台方法(逻辑都写在了一起,有点乱,分布式文件系统还没做好,暂时存在了本地...):
1 ///2 /// 图片上传 [FromBody]string token 3 /// 4 ///5 [HttpPost] 6 [Route("api/Upload/ImgUpload")] 7 public Task ImgUpload() 8 { 9 // 检查是否是 multipart/form-data 10 if (!Request.Content.IsMimeMultipartContent("form-data")) 11 throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 12 13 // 文件保存目录路径 14 const string saveTempPath = "~/UploadFiles/"; 15 var dirTempPath = HttpContext.Current.Server.MapPath(saveTempPath); 16 17 // 设置上传目录 18 var provider = new MultipartFormDataStreamProvider(dirTempPath); 19 20 var task = Request.Content.ReadAsMultipartAsync(provider). 21 ContinueWith (o => 22 { 23 var hash = new Hashtable(); 24 var file = provider.FileData[0]; 25 // 最大文件大小 26 const int maxSize = 10000000; 27 // 定义允许上传的文件扩展名 28 const string fileTypes = "gif,jpg,jpeg,png,bmp"; 29 30 // token验证 31 var token = string.Empty; 32 try 33 { 34 token = provider.FormData["token"].ToString(); 35 } 36 catch (Exception exception) 37 { 38 throw new Exception("未附带token,非法访问!", exception); 39 } 40 41 if (!string.IsNullOrEmpty(token)) 42 { 43 if (!CacheManager.TokenIsExist(token)) 44 { 45 throw new UserLoginException("Token已失效,请重新登陆!"); 46 } 47 if (accountInfoService.Exist_User_IsForzen(AccountHelper.GetUUID(token))) 48 { 49 CacheManager.RemoveToken(token); 50 tempCacheService.Delete_OneTempCaches(new Guid(token)); 51 throw new UserLoginException("此用户已被冻结,请联系管理员(客服)!"); 52 } 53 } 54 else 55 { 56 throw new Exception("token为空,非法访问!"); 57 } 58 59 string orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"'); 60 var fileinfo = new FileInfo(file.LocalFileName); 61 if (fileinfo.Length <= 0) 62 { 63 hash["Code"] = -1; 64 hash["Message"] = "请选择上传文件。"; 65 } 66 else if (fileinfo.Length > maxSize) 67 { 68 hash["Code"] = -1; 69 hash["Message"] = "上传文件大小超过限制。"; 70 } 71 else 72 { 73 var fileExt = orfilename.Substring(orfilename.LastIndexOf('.')); 74 75 if (String.IsNullOrEmpty(fileExt) || 76 Array.IndexOf(fileTypes.Split(','), fileExt.Substring(1).ToLower()) == -1) 77 { 78 hash["Code"] = -1; 79 hash["Message"] = "不支持上传文件类型。"; 80 } 81 else 82 { 83 try 84 { 85 AttachmentFileResultDTO attachmentFileResult; 86 attachmentFileService.UploadAttachmentFile(fileinfo, dirTempPath, fileExt, 87 Path.GetFileNameWithoutExtension(file.LocalFileName), out attachmentFileResult); 88 89 hash["Code"] = 0; 90 hash["Message"] = "上传成功"; 91 hash["FileId"] = attachmentFileResult.ID; 92 hash["FileName"] = attachmentFileResult.FileName + attachmentFileResult.FileType; 93 hash["NetImageUrl"] = attachmentFileResult.FileUrl; 94 } 95 catch (Exception exception) 96 { 97 throw new Exception("上传失败!", exception); 98 } 99 }100 }101 return hash;102 });103 return task;104 }
注:
1.第31行至57行是对附带参数token进行验证,因为博主的需求是只开放登录用户上传图片
2.第34行一定要tostring(),因为我们的参数也是以二进制数据格式上传的
前台目前是以jquery做的测试,使用了ajaxfileupload.js来上传文件。不过博主下载的ajaxfileupload.js并不支持附带参数上传,不知道是不是没找到好资源,不管了,自己打开文件瞅瞅...源码也不长一两百行,那就自己动手改改呗。(如果你已下载到支持附带参数上传的js,请自动忽略这一部分)
找到createUploadForm这个函数,OK,顾名思义它是用来创建FORM的,看看博主下载版本的源码:
1 createUploadForm: function (id, fileElementId) { 2 //create form 3 var formId = 'jUploadForm' + id; 4 var fileId = 'jUploadFile' + id; 5 var form = jQuery(''); 6 var oldElement = jQuery('#' + fileElementId); 7 var newElement = jQuery(oldElement).clone(); 8 jQuery(oldElement).attr('id', fileId); 9 jQuery(oldElement).before(newElement);10 jQuery(oldElement).appendTo(form);11 //set attributes12 jQuery(form).css('position', 'absolute');13 jQuery(form).css('top', '-1200px');14 jQuery(form).css('left', '-1200px');15 jQuery(form).appendTo('body');16 return form;17 },
我们添加参数data,并在第5行后面插入下列代码:
1 if (data) {2 for (var i in data) {3 if (data.hasOwnProperty(i)) {4 jQuery('').appendTo(form);5 }6 }7 }
再找到调用这个函数的地方,ajaxFileUpload函数中有这样一行:
var form = jQuery.createUploadForm(id, s.fileElementId);
OK,修改成我们重构后的调用:
var form = jQuery.createUploadForm(id, s.fileElementId,(typeof(s.data) == 'undefined' ? false : s.data));
到这一步,我们就可以jquery调用ajaxfileupload执行文件上传并且附带参数了。
1 $.ajaxFileUpload({ 2 url: "/api/Upload/ImgUpload", 3 secureuri: false, 4 fileUpload: file, 5 dataType: 'json', 6 data: { "token": token }, 7 success: function (data, status) { 8 var str = $(data).text(); 9 var result = JSON.parse(str);10 successFn(result, key);11 }, error: function (data, status, e) {12 failFn();13 }14 });
具体的ajaxfileupload.js下载路径:http://download.csdn.net/detail/cb511612371/9173749
附上做测试随意写的文件上传通用方法一份,可能有点丑...求轻喷(会有部分逻辑是博主测试的功能需求决定的,如使用,请自己过滤处理)
1 //图片上传 2 window.proHub = {}; 3 common = {}; 4 /**================================================================ 5 文件上传 6 =================================================================*/ 7 common.uploadTemplate = '
如果有写的不好或不对的地方,欢迎指出,必定及时纠正,虚心请教。
原创文章,代码都是从自己项目里贴出来的。转载请注明出处哦,亲~~~