.Net Core WebApi上传图片的方式(两种)
.Net Core WebApi上传图片的两种方式
我这边主要是为了上传图片,话不多说,上代码。
方式一:通过Form表单上传
后端:
/// <summary> /// 上传图片,通过Form表单提交 /// </summary> /// <returns></returns> [Route("Upload/FormImg")] [HttpPost] public ActionResult UploadImg(List<IFormFile> files) { if (files.Count<1) { return Error("文件为空"); } //返回的文件地址 List<string> filenames = new List<string>(); var now = DateTime.Now; //文件存储路径 var filePath = string.Format("/Uploads/{0}/{1}/{2}/", now.ToString("yyyy"), now.ToString("yyyyMM"), now.ToString("yyyyMMdd")); //获取当前web目录 var webRootPath = _hostingEnvironment.WebRootPath; if (!Directory.Exists(webRootPath + filePath)) { Directory.CreateDirectory(webRootPath + filePath); } try { foreach (var item in files) { if (item != null) { #region 图片文件的条件判断 //文件后缀 var fileExtension = Path.GetExtension(item.FileName); //判断后缀是否是图片 const string fileFilt = ".gif|.jpg|.jpeg|.png"; if (fileExtension == null) { break; //return Error("上传的文件没有后缀"); } if (fileFilt.IndexOf(fileExtension.ToLower(), StringComparison.Ordinal) <= -1) { break; //return Error("请上传jpg、png、gif格式的图片"); } //判断文件大小 long length = item.Length; if (length > 1024 * 1024 * 2) //2M { break; //return Error("上传的文件不能大于2M"); } #endregion var strDateTime = DateTime.Now.ToString("yyMMddhhmmssfff"); //取得时间字符串 var strRan = Convert.ToString(new Random().Next(100, 999)); //生成三位随机数 var saveName = strDateTime + strRan + fileExtension; //插入图片数据 using (FileStream fs = System.IO.File.Create(webRootPath + filePath + saveName)) { item.CopyTo(fs); fs.Flush(); } filenames.Add(filePath + saveName); } } return Success(filenames); } catch (Exception ex) { //这边增加日志,记录错误的原因 //ex.ToString(); return Error("上传失败"); } }
我这里主要是为了提交图片数据,所以有比较多的对图片文件的条件判断,这里可以根据需求,自行调整。包括文件的存储方式。
前端:
<!DOCTYPE html> <html> <head> <title>.Net Core WebApi图片上传</title> <meta charset="utf-8"/> <script type="text/javascript" src="/js/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="/js/jquery.form.min.js"></script> </head> <body> <h1>通过form表单提交</h1> <form id="myform" name="myform" method="post" enctype="multipart/form-data" action="https://localhost:44376/Upload/FormImg"> <input type="file" name="files" id="files" value="选择需要上传的文件" multiple /> <input type="button" id="submitbtn" value="提交" onclick="uplpadfile()"> </form> <div> 上传的图片,返回的地址 <div id="imglist">
</div> </div> <script type="text/javascript">
//前端第一种提交方式 function uplpadfile(){ //获取表单的数据 var formdata var file = $("#files").get(0); var files = file.files; var formdata = new FormData(); for (var i = 0; i < files.length; i++) { formdata.append("files", files[i]); } $.ajax({ type:'Post', data:formdata, contentType: false, processData: false, url:"https://localhost:44376/Upload/FormImg", success:function(result){ if (result.Success) { var imglist =result.Data; for(var i in imglist){ $("#imglist").append('<img src="'+imglist[i]+'"/>'); } }else{ alert('提交失败,重新尝试提交'); } } }) }; </script> </body> </html>
除了上传写的提交方式,另外还有两种提交数据的方式:
方式二:
function uplpadfile(){ //获取表单的数据 var formdata = new FormData(document.getElementById("myform")); $.ajax({ type:'Post', data:formdata, contentType: false, processData: false, url:"https://localhost:44376/Upload/FormImg", success:function(result){ if (result.Success) { var imglist =result.Data; for(var i in imglist){ $("#imglist").append('<img src="'+imglist[i]+'"/>'); } }else{ alert('提交失败,重新尝试提交'); } } }) }; </script>
方式三:
<script type="text/javascript"> function uplpadfile(){ $("#myform").ajaxSubmit(function(result){ if (result.Success) { var imglist =result.Data; for(var i in imglist){ $("#imglist").append('<img src="'+imglist[i]+'"/>'); } }else{ alert('提交失败,重新尝试提交'); } }); }; </script>
前端这里,要注意几点:
1、Form表中一定要加上 enctype="multipart/form-data" 标签
2、文件上传的 file 控件上,如果要一次上传多张图片,需要加上 multiple 标签
3、方式一中: formdata.append("files", files[i]) 的 files 必须和接口接受文件的参数名一致
4、方式二和方式三中:<input type="file" name="files"> 中的 name 必须和接口接受文件的参数名一致
通过Form提交文件的方式总结:
前端提交文件的三种方式都可以使用。
如果文件需要和表单中其他数据一起提交,可以使用方式二和方式三。
如果只要单独提交一个文件数据,可以使用方式一。
====================华丽的分割线====================
方式二:通过Base64字符上传
后端:
/// <summary> /// 文件上传,Base64 /// </summary> /// <param name="fileBase64">Base64</param> /// <param name="fileName">文件名</param> /// <returns></returns> [HttpPost] [Route("Upload/Base64")] public ActionResult UploadBase64(string fileBase64, string fileName) { byte[] bytes = fileBase64.ToBytes_FromBase64Str(); var fileExtension = Path.GetExtension(fileName); var strDateTime = DateTime.Now.ToString("yyMMddhhmmssfff"); //取得时间字符串 var strRan = Convert.ToString(new Random().Next(100, 999)); //生成三位随机数 var saveName = strDateTime + strRan + fileExtension; var savePath = "Upload/Img/" + DateTime.Now.ToString("yyyyMMdd") + "/" + saveName; string filePath = "https://oss.tiaobox.com/" + savePath; try { //将文件上传到阿里云oss using (MemoryStream m = new MemoryStream(bytes)) { var client = new OssClient(aliyunconfig.EndPoint, aliyunconfig.AccessKeyID, aliyunconfig.AccessKeySecret); PutObjectRequest _objRequest = new PutObjectRequest(aliyunconfig.BucketName, savePath, m); client.PutObject(_objRequest); } return Success(filePath); } catch (Exception ex) { WriteSysLog(ex.ToString(), Entity.Base_SysManage.EnumType.LogType.接口调用异常); return Error("上传失败!"); } }
这个后端方法,每次只能上传一个文件,前端需要把文件转成Base64的字符提交。
这里保存数据的方式,是保存到阿里云的OSS上,也可以采用上面的方法,保存的本地。最终都是返回文件的路径。
前端:
<!DOCTYPE html> <html> <head> <title>.Net Core WebApi图片上传</title> <meta charset="utf-8"/> <script type="text/javascript" src="/js/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="/js/jquery.form.min.js"></script> </head> <body> <h1>通过文件转为Base64字符提交</h1> <input type="file" name="basefile" id="basefile" value="选择需要上传的文件" multiple /> <script type="text/javascript"> $("#basefile").change(function(){ var basefile = base64(document.getElementById("basefile")); }) //上传文件 function updateBackground(filename,imgurl){ //提交前,去除格式标记 imgurl = imgurl.replace("data:image/jpeg;base64,", "").replace("data:image/png;base64,", "").replace("data:image/jpg;base64,", "").replace("data:image/gif;base64,", "").replace("data:image/bmp;base64,", ""); // urlElement.innerHTML = imgurl; var businessParam = { fileBase64:imgurl, fileName:filename }; $.ajax({ url:'https://localhost:44376/Upload/Base64', data:businessParam, type:'post', dataType:'json', success:function(result){ if (result.Success) { alert("上传成功"); }else{ alert("上传失败"); } }, error: function(data) { alert("error:"+data.Error); } }) } //文件转为Base64 function base64(file) { if (typeof (FileReader) === 'undefined') { alert("抱歉,你的浏览器不支持 FileReader,请使用现代浏览器操作!"); } var reader = new FileReader(); var pos = file.files[0].name.lastIndexOf("."); var type = file.files[0].name.substring(pos + 1); //判断文件格式 if (type.toLowerCase() != "png" && type.toLowerCase() != 'jpg' && type.toLowerCase() != 'jpeg' && type.toLowerCase() != 'gif' && type.toLowerCase() != 'bmp') { alert("格式错误,请上传'png、jpg、jpeg、bmp、gif'格式文件"); return; } reader.onloadend = ( function(e) { imgurl = e.target.result; updateBackground(file.files[0].name,imgurl); } ); // Read the file reader.readAsDataURL(file.files[0]); } </script> </body> </html>
这里需要注意的是文件在前端转成Base64字符后,需要在字符的前面去掉文件的格式标签。不然到后端会无法正常读取Base64的字符。
或者在后端接收数据后,做处理也可以。
补充:
_hostingEnvironment的定义
private readonly IHostingEnvironment _hostingEnvironment; public UploadController(IHostingEnvironment hostingEnvironment,IOptions<AliyunConfig> _aliyunconfig) { _hostingEnvironment = hostingEnvironment; aliyunconfig = _aliyunconfig.Value; }
ToBytes_FromBase64Str 是对 String 类的方法扩展
public static byte[] ToBytes_FromBase64Str(this string base64Str) { return Convert.FromBase64String(base64Str); }
如果有什么错误或者欠缺的地方,欢迎指正,互相学习。
文章参考,里面还有讲述关于大文件的上传:
https://www.cnblogs.com/seabluescn/p/9229760.html