我這邊主要是為了上傳圖片,話不多說,上代碼。
方式一:通過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
轉:https://www.cnblogs.com/leoxuan/articles/11087121.html