ASP.NET 页面无刷新上传图片
作为一只菜鸟新人,同时又带点强迫症的我,在做asp.net的项目中,使用FileUpload控件上传图片时,不能进行预览,而且如果有验证时页面又会刷新导致选择的文件也会刷新消失,就体验非常不好。所以就想着怎么才能上传图片可以选择预览,同时又直接上传。通过网上的查询也是发现了很多办法,但是怎奈才疏学浅看不懂啊...
但是,在我的 “东拼西凑” 下,还是实现了想要的功能,这里来分享下我的方法,大佬们不要嫌弃。
操作步骤:
一、用FileUpload/input获取选择的图片进行编码(这里两者的区别不大)
二、将编码通过ajax返回到asp.net的后台
三、后台进行解码
四、图片文件保存
其实看着还是挺简单的
一、获取选择的图片
因为需要使用ajax进行异步传值,js原生的写着太麻烦了就用的jquery封装好的。所以先引入jquery文件,再简单的放入一个图片控件用来显示,一个文件上传控件。
接下来就是编码操作,这里是通过FileReader对象的readAsDataURL()方法对图像进行Base64编码
1 //获取元素,img,文件上传控件 2 var img = $("#img"); 3 var fuImg = $("#fuImg"); 4 //设置上传控件的change事件 5 fuImg.change(function () { 6 var file = this.files[0]; 7 //判断文件类型 8 if (file.type.indexOf("image") == -1) { 9 alert("请选择图片文件!"); 10 return; 11 } 12 //判断文件大小 13 if (file.size > 1024 * 1024 * 3) { 14 alert("图片过大,请选择小于3M的图片"); 15 return; 16 } 17 //创建Reader对象 18 var reader = new FileReader(); 19 //通过 20 reader.readAsDataURL(file); 21 reader.onload = function (fl) { 22 var ImgCoding = reader.result; 23 //通过ajax将图片编码传回后台 24 25 } 26 })
二、将编码通过ajax返回到asp.net的后台
使用jquery封装好的ajax就非常的简单了,直接套用格式
1 $.ajax({ 2 type: "Post",//请求类型分为post和get 3 url: "Default.aspx/SaveImg",//像服务器请求的地址,Default.aspx里面的SaveImg方法 4 data: "{ImgCoding:'" + ImgCoding + "'}",//返回参数ImgCoding就是编码的图片 5 contentType: "application/json; charset=utf-8",//向服务器发送内容的类型,默认值是:application/x-www-form-urlencoded 6 dataType: "json",//预期服务器响应类型 7 timeout: '5000',//设置本地的请求超时时间(单位是毫秒) 8 //成功后返回执行的方法 9 success: function (data) { 10 if (data.d != "") { 11 img.attr("src",data.d); 12 } else { 13 alert("图片保存失败!"); 14 } 15 }, 16 //失败后返回执行的方法 17 error: function (err) { 18 alert("图片上传出错!") 19 } 20 });
三、后台进行解码
首先创建ajax请求的那个方法,要使ajax能能直接访问这个方法则需要在方法前标识[WebMehtod],还需引入命名空间using System.Web.Services;不然程序将报错无法执行。
1 [WebMethod] 2 public static string SaveImg(string ImgCoding) 3 { 4 //对编码进行处理 5 ImgCoding = DisposeCode(ImgCoding); 6 //解码 7 8 //返回保存的路径 9 10 }
图片经过readAsDataURL()编码后是这样的,不能够直接进行解码,需要先进行编码的处理
处理方法就是删除编码头部,对不能识别的字符进行替换。
1 public static string DisposeCode(string ImgCoding) 2 { 3 //过滤编码头部 4 ImgCoding = ImgCoding.Replace("data:image/jpeg;base64", "").Replace("data:image/png;base64", "").Replace("data:image/gif;base64", ""); 5 //过滤不能识别的字符 6 ImgCoding = ImgCoding.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+"); 7 if (ImgCoding.Length % 4 > 0) 8 { 9 ImgCoding = ImgCoding.PadRight(ImgCoding.Length + 4 - ImgCoding.Length % 4, '='); 10 } 11 //返回编码后的字符串 12 return ImgCoding; 13 }
然后进行解码
1 [WebMethod] 2 public static string SaveImg(string ImgCoding) 3 { 4 //对编码进行处理 5 ImgCoding = DisposeCode(ImgCoding); 6 //解码 7 byte[] arr2 = Convert.FromBase64String(ImgCoding);//转换为字节 8 MemoryStream stream = new MemoryStream(arr2);//创建数据流 9 Bitmap img = new Bitmap(stream);//创建位图 10 //返回路径 11 12 }
四、文件保存
为了避免文件重复和便于处理,这里我是通过获取当前日期进行配置文件路径的,“年月日(yyyyMMdd)”为文件夹,“时分秒毫秒(HHmmssffff)”为文件名。
例如:
文件创建的方法
1 public static string CreateImgFilePath() { 2 //获取页面对象 3 Default d = new Default(); 4 //创建文件目录地址 5 string filename = DateTime.Now.ToString("yyyyMMdd"); 6 //判断地址是否存在 --这里判断不存在-创建目录 7 if (!Directory.Exists(d.Server.MapPath("~/Images/"+filename))) 8 { 9 Directory.CreateDirectory(d.Server.MapPath("~/Images/" + filename)); 10 } 11 //生成完整的图片路径 12 filename=filename+"/"+ DateTime.Now.ToString("HHmmssffff") + ".jpg"; 13 //返回 14 return filename; 15 }
文件保存
1 [WebMethod] 2 public static string SaveImg(string ImgCoding) 3 { 4 //对编码进行处理 5 ImgCoding = DisposeCode(ImgCoding); 6 //解码 7 byte[] arr2 = Convert.FromBase64String(ImgCoding); 8 MemoryStream stream = new MemoryStream(arr2); 9 Bitmap img = new Bitmap(stream); 10 Default d = new Default(); 11 //获取图片地址 12 string FilePath = CreateImgFilePath(); 13 //保存图片 14 img.Save(d.Server.MapPath("~/Images/" + FilePath)); 15 //返回路径 16 return "Images/" + FilePath; 17 }
写到这里就可以进行测试上传了
这样可以看到上传成功了
但是。。。试着试着毛病就出来了
当我文件换的大点的时候
就这样的了...打开调试工具
“status of 500”服务器端的错误,然后又去求助百度...最后找到了原因:ajax 请求 服务器 响应内容过长
解决方法就是在web.config中加入
1 <system.web.extensions> 2 <scripting> 3 <webServices> 4 <jsonSerialization maxJsonLength="1024000000"/> 5 </webServices> 6 </scripting> 7 </system.web.extensions>
这样问题就解决了
最后:源码奉上(点击下载)
有兴趣可以看看base64编码“ztKwrsTj”解码是什么意思。