本章和大家分享的是.NetCore的MVC框架上傳文件的示例,主要講的內(nèi)容有:form方式提交上傳,ajax上傳,ajax提交+上傳進(jìn)度效果,Task并行處理+ajax提交+上傳進(jìn)度,相信當(dāng)你讀完文章內(nèi)容后能后好的收獲,如果可以不妨點個贊;由于昨天電腦沒電了,快要寫完的內(nèi)容沒有保存,今天早上提前來公司從頭開始重新,斷電這情況的確讓人很頭痛啊,不過為了社區(qū)的分享環(huán)境,這也是值得的,不多說了來進(jìn)入今天的正篇環(huán)節(jié)吧;

form方式上傳一組圖片

先來看看咋們html的代碼,這里先簡單說下要上傳文件必須要設(shè)置form元素里面的 enctype="multipart/form-data" 屬性和post方式,如果你想要多選上傳文件的話,需要把文件type='file'元素設(shè)置她的屬性multiple='multiple',因此就有了如下內(nèi)容:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

1 <form class="form-horizontal" action="/Home/FileUp" method="post" enctype="multipart/form-data">2 3                 <input type="file" name="MyPhoto" class="form-control" multiple />4                 <br />5                 <button class="btn btn-default">form上傳</button>6                 <br />7                 <span style="color:red">@ViewData["MsgBox"]</span>8             </form>

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

由于采用form提交,這個測試用例只接用了button元素默認(rèn)的type=submit來提交表單,對應(yīng)的后臺Action中代碼如下:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

 1 /// <summary> 2         /// form提交上傳 3         /// </summary> 4         /// <param name="user"></param> 5         /// <returns></returns> 6         [HttpPost] 7         public async Task<IActionResult> FileUp(MoUser user) 8         { 9             if (user.MyPhoto == null || user.MyPhoto.Count <= 0) { MsgBox("請上傳圖片。"); return View(); }10             //var file = Request.Form.Files;11             foreach (var file in user.MyPhoto)12             {13                 var fileName = file.FileName;14                 var contentType = file.ContentType;15                 var len = file.Length;16 17                 var fileType = new string[] { "image/jpeg", "image/png" };18                 if (!fileType.Any(b => b.Contains(contentType))) { MsgBox($"只能上傳{string.Join(",", fileType)}格式的圖片。"); return View(); }19 20                 if (len > 1024 * 1024 * 4) { MsgBox("上傳圖片大小只能在4M以下。"); return View(); }21 22                 var path = Path.Combine(@"D:\F\學(xué)習(xí)\vs2017\netcore\netcore01\WebApp01\wwwroot\myfile", fileName);23                 using (var stream = System.IO.File.Create(path))24                 {25                     await file.CopyToAsync(stream);26                 }27             }28             MsgBox($"上傳成功");29 30             return View();31         }

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

從前端到后端的Action不得不說這種form表單提交的方式挺簡單的,需要注意的是Action這里用的實體模型方式來對應(yīng)上傳的文件信息,這里自定義了MoUser類,通過屬性 public List<IFormFile> MyPhoto { getset; } 來匹配html表單中文件type='file'的name屬性名稱name="MyPhoto":

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

1 public class MoUser2     {3         public int UserId { get; set; } = 1;4         public string UserName { get; set; } = "神牛步行3";5 6         public List<IFormFile> MyPhoto { get; set; }7     }

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

這樣就能通過實體模型的方式把上傳的文件信息存儲在自定義MoUser類中的MyPhoto屬性中了;

ajax上傳一組圖片

這里需要在上面例子中的html處修改一些東西,不再使用form提交,指定了普通button按鈕來觸發(fā)ajax的提交,完整html代碼如:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

1 <form class="form-horizontal" id="form01" method="post" enctype="multipart/form-data">2 3                 <input type="file" name="MyPhoto01" class="form-control" multiple />4                 <br />5                 <button type="button" id="btnAjax" class="btn btn-default">ajax上傳</button>6                 <br />7                 <span style="color:red" id="span01"></span>8             </form>

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

有了布局,再來看看具體的js實現(xiàn)代碼,這里我采用jquery的ajax提交的方法來操作,也用到了html5新增的FormData來存儲表單的數(shù)據(jù):

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

 1 $("#btnAjax").on("click", function () { 2             var msg = $("#span01"); 3             var form = document.getElementById("form01"); 4             //console.log(form); 5             var data = new FormData(form); 6  7             $.ajax({ 8                 type: "POST", 9                 url: "/home/AjaxFileUp",10                 data: data,11 12                 contentType: false,13                 processData: false,14                 success: function (data) {15                     if (data) {16                         msg.html(data.msg);17                     }18                 },19                 error: function () {20                     msg.html("上傳文件異常,請稍后重試!");21                 }22             });23         });

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

至于后臺Action的方法和示例一的相差不大,關(guān)鍵點在于這里我直接使用 Request.Form.Files 方式來獲取上傳的所有文件,不再使用實體模型的方式了,這樣測試用例更多樣化吧:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

 1 /// <summary> 2         /// ajax無上傳進(jìn)度效果上傳 3         /// </summary> 4         /// <returns></returns> 5         [HttpPost] 6         public async Task<JsonResult> AjaxFileUp() 7         { 8             var data = new MoData { Msg = "上傳失敗" }; 9             try10             {11                 var files = Request.Form.Files.Where(b => b.Name == "MyPhoto01");12                 //非空限制13                 if (files == null || files.Count() <= 0) { data.Msg = "請選擇上傳的文件。"; return Json(data); }14 15                 //格式限制16                 var allowType = new string[] { "image/jpeg", "image/png" };17                 if (files.Any(b => !allowType.Contains(b.ContentType)))18                 {19                     data.Msg = $"只能上傳{string.Join(",", allowType)}格式的文件。";20                     return Json(data);21                 }22 23                 //大小限制24                 if (files.Sum(b => b.Length) >= 1024 * 1024 * 4)25                 {26                     data.Msg = "上傳文件的總大小只能在4M以下。"; return Json(data);27                 }28 29                 //寫入服務(wù)器磁盤30                 foreach (var file in files)31                 {32 33                     var fileName = file.FileName;34                     var path = Path.Combine(@"D:\F\學(xué)習(xí)\vs2017\netcore\netcore01\WebApp01\wwwroot\myfile", fileName);35                     using (var stream = System.IO.File.Create(path))36                     {37                         await file.CopyToAsync(stream);38                     }39                 }40                 data.Msg = "上傳成功";41                 data.Status = 2;42 43             }44             catch (Exception ex)45             {46                 data.Msg = ex.Message;47             }48             return Json(data);49         }

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

如果你有耐心讀到這里,那么后面的內(nèi)容個人感覺對你開發(fā)會有好的幫助,不負(fù)你期待;

ajax提交+上傳進(jìn)度+一組圖片上傳

同樣我們先來看對應(yīng)的html代碼,其實和示例2幾乎一樣,只是把名稱變動了下:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

1 <form class="form-horizontal" id="form02" method="post" enctype="multipart/form-data">2 3                 <input type="file" name="MyPhoto02" class="form-control" multiple />4                 <br />5                 <button type="button" id="btnAjax02" class="btn btn-default">ajax上傳進(jìn)度效果上傳</button>6                 <br />7                 <span style="color:red" id="span02"></span>8             </form>

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

要加一個進(jìn)度效果,需要用到j(luò)s的定時器,定時獲取上傳文件的上傳進(jìn)度數(shù)據(jù)信息,因此這里通過js的setInterval方法來定時請求一個進(jìn)度數(shù)據(jù)接口,注意用完之后需要清除這個定時器,不然一直再不斷請求您接口:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

 1 $("#btnAjax02").on("click", function () { 2  3             var interBar; 4             var msg = $("#span02"); 5             msg.html("上傳中,請稍后..."); 6             var form = document.getElementById("form02"); 7             //console.log(form); 8             var data = new FormData(form); 9 10             $.ajax({11                 type: "POST",12                 url: "/home/AjaxFileUp02",13                 data: data,14 15                 contentType: false,16                 processData: false,17                 success: function (data) {18                     if (data) {19                         msg.html(data.msg);20                         //清除進(jìn)度查詢21                         if (interBar) { clearInterval(interBar); }22                     }23                 },24                 error: function () {25                     msg.html("上傳文件異常,請稍后重試!");26                     if (interBar) { clearInterval(interBar); }27                 }28             });29 30             //獲取進(jìn)度31             interBar = setInterval(function () {32 33                 $.post("/home/ProgresBar02", function (data) {34                  35                     if (data) {36                         var isClearVal = true;37                         var strArr = [];38                         $.each(data, function (i, item) {39                             strArr.push('文件:' + item.fileName + ",當(dāng)前上傳:" + item.percentBar + '<br/>');40                             if (item.status != 2) { isClearVal = false; }41                         });42                         msg.html(strArr.join(''));43                         if (isClearVal) {44                             if (interBar) { clearInterval(interBar); }45                         }46                     }47                 });48             }, 200);49         });

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

既然上面說到單獨(dú)的進(jìn)度數(shù)據(jù)接口,那么我們除了上傳Action外,也需要進(jìn)度的Action,而這進(jìn)度Action得到的上傳文件數(shù)據(jù)信息必須和上傳的Action一直,因此就需要用到緩存等存儲數(shù)據(jù)的方式,這里我用的是MemoryCache的方式,對已netcore來說僅僅只需要在起始文件(如:Startup.cs)中添加組件服務(wù):

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

1 public void ConfigureServices(IServiceCollection services)2         {3             // Add framework services.4             services.AddMvc();5 6             //添加cache支持7             services.AddDistributedMemoryCache();8         }

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

然后通過構(gòu)造函數(shù)注入到對應(yīng)的接口Controller中去:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

1         readonly IMemoryCache _cache;2 3         public HomeController(IOptions<MoOptions> options, ILogger<HomeController> logger, IMemoryCache cache)4         {5             this._options = options.Value;6             _logger = logger;7             _cache = cache;8         }

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

到此我們就能利用cache來存儲我們上傳進(jìn)度信息了,來看下處理上傳的Action:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

  1 private string cacheKey = "UserId_UpFile";  2         private string cacheKey03 = "UserId_UpFile03";  3         /// <summary>  4         /// ajax上傳進(jìn)