本代码实现图片文件上传并生成缩略图以及文件安全效验等。
多文件上传效果只兼容 IE10、firefox、chrome 等浏览器,其他浏览器只能单文件上传。
事件:
开发代码中一般使用传统的FileUpload控件进行单个文件上传,选择图片文件时又无法达到实时预览的效果,而且无法实施对多件文件一次性上传。
实现图片预览在第二篇中详细描述,请关注。
代码架构图:
--- AjaxUploadFileContral
---- cs
----ajax.aspx //ajax页面
----Encryption.cs //加解密操作基类
----JSONHelper.cs //json操作基类
----Result.cs //保存对象类
----UploadFileClass.cs //文件上传操作基类
---- css
----css.css
---- img //资源图片
---- js
----jquery-1.4.2.min.js
----uploadfile.js //文件上传js类
--- temp //图片临时文件夹
--- ajaxUF.ascx //文件上传控件
--- UploadFile.aspx //文件接收页面
---- Image //站点图片文件夹
---- Default.aspx //主页面,测试
---- Web.config
初步效果图(火狐下):
实施逻辑:
1、主界面使用框架嵌套文件接收页面,通过File控件选择多个文件后,将文件Post提交至文件接收页面。
2、接收页面将传入的文件图片保存至站点临时目录,保存完成后读取临时目录中的图片进行预览以及保存(预览图片为缩略图)。
3、caozuo.html" target="_blank">删除操作:将选中的图片及缩略图从临时目录中删除。
4、保存:将选中的图片及缩略图全部移动到站点指定图片目录。
5、取消上传:删除临时目录里的所有文件。
说明:
第2步骤中需同时生成图片缩略图以及效验文件安全。
主要代码模块:
文件效验模块
5 /// <summary> 6 /// 效验文件安全性 7 /// 将效验文件正确格式,即使更改文件类型及扩展名也无法通过此效验方法 8 /// </summary> 9 public static Result checkFile(string FilePath) 10 { 11 try 12 { 13 FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read); 14 BinaryReader r = new BinaryReader(fs); 15 string fileclass = ""; 16 byte buffer = r.ReadByte(); 17 fileclass = buffer.ToString(); 18 buffer = r.ReadByte(); 19 fileclass += buffer.ToString(); 20 r.Close(); 21 fs.Close(); 22 23 //文件类型错误,将删除文件 24 bool falg = false; 25 string[] FileType = new string[] { "255216", "7173", "13780" }; 26 //数字说明,只针对目前主流图片格式: 27 //255216 代表 .jpg文件 28 //13780 代表 .png文件 29 //7173 代表 .gif文件 30 foreach (string n in FileType) 31 { 32 if (fileclass == n) 33 { 34 falg = true; 35 break; 36 } 37 } 38 if (!falg) 39 { 40 File.Delete(FilePath); 41 return new Result(-1,"上传文件为非法文件,请谨慎上传。"); 42 } 43 return new Result(1,"true"); 44 } 45 catch (Exception ex) 46 { 47 throw ex; 48 } 49 }
图片缩略图生成模块
5 /// <summary> 6 /// 生成图片缩略图 7 /// </summary> 8 /// <param name="filePath">图片地址</param> 9 /// <param name="newFileName">缩略图地址</param> 10 public static string CreateThumbnailImage(string filePath, string newFileName) 11 { 12 try 13 { 14 if (File.Exists(filePath)) 15 { 16 System.Drawing.Image copyImage = System.Drawing.Image.FromFile(filePath); 17 //为写入缩略图委托事件 18 System.Drawing.Image.GetThumbnailImageAbort callb = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback); 19 System.Drawing.Image ReducedImage = copyImage.GetThumbnailImage(ThumbnailImgWidth, ThumbnailImgHeigth, callb, IntPtr.Zero); //获取缩略图 20 //保存缩略图 21 ReducedImage.Save(newFileName, System.Drawing.Imaging.ImageFormat.Jpeg); 22 ReducedImage.Dispose(); 23 copyImage.Dispose(); 24 return newFileName; 25 } 26 } 27 catch (Exception ex) 28 { 29 throw ex; 30 } 31 return string.Empty; 32 } 33 34 /// <summary> 35 /// 构造方法 为委托事件写入缩略图 36 /// </summary> 37 public static bool ThumbnailCallback() 38 { 39 return false; 40 }
获取页面post传递的文件,保存至临时目录
5 /// <summary> 6 /// 获取post的文件方法,将图片文件保存至临时文件夹,并生成缩略图 7 /// </summary> 8 /// <param name="req"></param> 9 public static void UploadImgToTempAndCreataThumbnailImage(HttpRequest req) 10 { 11 try 12 { 13 int filesCount = req.Files.Count; //获取请求流里的文件个数 14 if (filesCount > 0) 15 { 16 bool falg = true; 17 for (int i = 1; i <= filesCount; i++) 18 { 19 string fileName = req.Files[i - 1].FileName; //文件名称 20 //在此只做普通扩展名过滤,请在程序后台代码中详细过滤 21 if (fileName.IndexOf(".exe") > -1) 22 falg = false; 23 if (falg) 24 { 25 //获取图片需暂存的临时目录 26 string url = UploadFileClass.getTmpRootUrlMapPath() + fileName; 27 lock (url) 28 { 29 //先删除缓存图片 30 File.Delete(url); 31 32 //将文件存入临时目录 33 req.Files[i - 1].SaveAs(url); 34 35 //效验文件以及产生缩略图 36 string newT = fileName; 37 if (File.Exists(url)) 38 { 39 //效验文件 40 Result rsCheck = checkFile(url); 41 if (rsCheck.Code == 1) 42 { 43 //以 原有文件名后加入后缀: _T 命名缩略图 44 string FileExtensionName = fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf(".")); 45 string newFileName = fileName.Replace(FileExtensionName, "_T" + FileExtensionName); 46 newT = newFileName; 47 48 //生成文件缩略图 49 UploadFileClass.CreateThumbnailImage(url, UploadFileClass.getTmpRootUrlMapPath() + newFileName); 50 } 51 } 52 } 53 } 54 } 55 } 56 } 57 catch (Exception ex) 58 { 59 throw ex; 60 } 61 }
传统服务器端控件文件上传代码模块
4 /// <summary> 5 /// 验证图片的格式并上传并生成图片缩略图以及水印图 6 /// </summary> 7 /// <param name="fup">FileUpload</param> 8 /// <returns></returns> 9 public static Result UploadFile(FileUpload fup) 10 { 11 if (!fup.HasFile) 12 { 13 return new Result(-1,"图片内容为空!"); 14 } 15 16 try 17 { 18 //上传文件大小限制 19 int filesizekb = fup.PostedFile.ContentLength / 1024; 20 if (filesizekb > UploadSize) 21 { 22 return new Result(-1, string.Format("文件大小超出限制!文件大小请控制在{0}KB", UploadSize)); 23 } 24 25 //文件扩展名及文件类型验证 26 if (CheckFileExtension(fup).Code != 1) 27 { 28 return new Result(-1, "请选择正确的图片格式!"); 29 } 30 31 //临时物理路径 32 string dirPath = getTmpRootUrlMapPath(); 33 if (!Directory.Exists(dirPath)) 34 { 35 Directory.CreateDirectory(dirPath); 36 } 37 string filepath = string.Format("{0}{1}", dirPath, fup.FileName); 38 39 //将文件上传至临时目录 40 fup.PostedFile.SaveAs(filepath); 41 //当上传成功后,判断文件类型 42 if (!File.Exists(filepath)) 43 { 44 return new Result(-1, "上传失败文件失败,未找到上传文件。"); 45 } 46 //安全效验文件 47 if (checkFile(filepath).Code != 1) 48 return new Result(-1, "非法图片文件!"); 49 50 //以 原有文件名后加入后缀: _T 命名缩略图 51 string FileExtensionName = Path.GetExtension(fup.FileName).ToLower(); 52 string newFileName = fup.FileName.Replace(FileExtensionName, "_T" + FileExtensionName); 53 //生成文件缩略图 54 UploadFileClass.CreateThumbnailImage(filepath, UploadFileClass.getTmpRootUrlMapPath() + newFileName); 55 56 return new Result(1, "文件上传成功!"); 57 } 58 catch (Exception ex) 59 { 60 throw ex; 61 } 62 }
保存文件模块
5 /// <summary> 6 /// 保存,实际操作就是将临时目录里的图片移动到站点目录 7 /// </summary> 8 /// <param name="fileName"></param> 9 /// <returns></returns> 10 public static Result MoveFile(string fileName) 11 { 12 try 13 { 14 string ImgsourceUrl = getTmpRootUrlMapPath() + fileName; 15 if (File.Exists(ImgsourceUrl)) 16 { 17 string ImgThumbnailSourceUrl = getTmpRootUrlMapPath() + fileName.Replace("_T", ""); 18 19 string mNewImgUrl = getImgRootUrlMapPath() + fileName; 20 string mNewImgThumbnailUrl = getImgRootUrlMapPath() + fileName.Replace("_T", ""); 21 22 File.Move(ImgsourceUrl, mNewImgUrl); 23 File.Move(ImgThumbnailSourceUrl, mNewImgThumbnailUrl); 24 } 25 return new Result(1, "保存文件成功"); 26 } 27 catch (Exception ex) 28 { 29 throw ex; 30 } 31 }
js 主要代码:
1 /// <summary> 2 /// 上传控件选择文件夹路径 3 /// </summary> 4 function selectFile(obj) { 5 //判断当前上传控件是否包含文件 6 //obj.files 此属性支持IE10、firefox、google chromed等浏览器 7 if (obj.files != undefined) { 8 if (obj.files.length != 0) { 9 //自动post到接收页面 10 document.forms[0].action = contralRoot + 'UploadFile.aspx'; 11 document.forms[0].method = "POST"; 12 document.forms[0].enctype = "multipart/form-data"; //允许传递文件 13 document.forms[0].target = "frame1"; 14 document.forms[0].submit(); 15 document.getElementById("frame1").height = "500px"; 16 document.getElementById("frame1").width = "100%"; 17 obj.value = ""; 18 } 19 } 20 //ie8及以下版本将调用提交按钮事件,但会刷新页面 21 else { 22 document.getElementById("ajaxUF_btnsave").click(); 23 } 24 }
共享盘源码下载地址:http://pan.baidu.com/s/1mg5OQtq(共享时间有限,如需源码可加我QQ)
源码中注意事项:
UploadFileClass.cs 全局变量设置
1 /// <summary> 2 /// 上传图片临时文件夹虚拟目录,一般为根目录下,必须保留路径前后的符号 ‘/’ 3 /// </summary> 4 public static readonly string tmpRootURL = "/AjaxUploadFileContral/temp/"; 5 6 /// <summary> 7 /// 图片站点目录,一般为根目录下,必须保留路径前后的符号 ‘/’ 8 /// </summary> 9 public static readonly string imgRootURL = "/Image/"; 10 11 /// <summary> 12 /// 定义列表单元格列数,将产生一个N列的表格 13 /// </summary> 14 public static readonly int listCellCount = 5; 15 16 /// <summary> 17 /// 缩略图宽度 18 /// </summary> 19 public static readonly int ThumbnailImgWidth = 100; 20 /// <summary> 21 /// 缩略图高度 22 /// </summary> 23 public static readonly int ThumbnailImgHeigth = 100; 24 25 /// <summary> 26 /// 限制文件大小300KB 27 /// </summary> 28 public static readonly int UploadSize = 300;
uploadfile.js 全局变量设置
1 var contralRoot = "/AjaxUploadFileContral/"; //定义全局控件所在目录
各个浏览效果图:
google chrome:
firefox :
IE8: