.NET和.NET Core Web APi FormData多文件上传
【導讀】最近因維護.NET和.NET Core項目用到文件上傳功能,雖說也做過,但是沒做過什么對比,借此將二者利用Ajax通過FormData上傳文件做一個總結,通過視圖提交表單太簡單,這里不做闡述,希望對有需要的童鞋能有力所能及的幫助。
.NET Web APi FormData文件上傳
我們將參數和文件都通過FormData來上傳,給出如下HTML代碼
?<div?class="form-horizontal"?style="margin-top:80px;"><div?class="form-group"><label?class="control-label?col-md-2"?for="caption">標題</label><div?class="col-md-10"><input?name="title"?id="title"?type="text"?/></div></div><div?class="form-group"><label?class="control-label?col-md-2"?for="caption">文件</label><div?class="col-md-10"><input?name="file"?id="file"?multiple?type="file"?/></div></div><div?class="form-group"><div?class="col-md-offset-2?col-md-10"><input?type="submit"?id="btn"?value="提交"?class="btn?btn-success"?/></div></div> </div>恕我有點強迫癥,界面好看點,看著也舒服,接下來則是腳本自然不用多說,利用FormData上傳文件網上一搜遍地都是
?$(function?()?{$('#btn').click(function?()?{var?data?=?new?FormData();var?title?=?$('#title').val();data.append("title",?title);var?files?=?$('#file')[0].files;;for?(var?i?=?0;?i?<?files.length;?i++)?{data.append("file",?files[i]);}$.ajax({url:?'/api/upload/upload',type:?"post",cache:?false,contentType:?false,processData:?false,data:?data,});}); });不過需要注意的是,對現代大多瀏覽器都都已支持將上述contentType設置為false后,就是在請求頭中添加multipart/form-data,若是老版本瀏覽器則需要在請求頭中手動添加表單多文件上傳標識,如下
前端我們已經搞完,接下來我們回到后臺,.NET Web APi已提供專門讀取FormData數據的APi,如下:
若上傳2個文件,此時上傳App_Data目錄下的文件,如下這般
?若要讀取提交的表單參數,我們如下獲取
//獲取表單參數數據 var?formData?=?provider.FormData;那么我們怎么將上述類似臨時文件數據轉換為我們上傳的文件數據呢?我們只需將上述文件名轉換我們上傳的文件名或者其他自定義文件名稱即可,如下:
//?獲取文件數據 foreach?(MultipartFileData?file?in?provider.FileData) {string?fileName?=?file.Headers.ContentDisposition.FileName;if?(fileName.StartsWith("\"")?&&?fileName.EndsWith("\"")){fileName?=?fileName.Trim('"');}if?(fileName.Contains(@"/")?||?fileName.Contains(@"\")){fileName?=?Path.GetFileName(fileName);}//將本地文件轉換為實際所需文件File.Move(file.LocalFileName,?Path.Combine(root,?fileName)); }當然除了通過上述流讀取表單相關數據外,.NET Web APi還提供了內存表單流,只是利用此流時,表單參數和文件放置在一起,我們需要通過文件相關參數來做區分,然后分別獲取文件和表單參數,如下:
var?provider?=?new?MultipartMemoryStreamProvider();await?Request.Content.ReadAsMultipartAsync(provider);var?formData?=?new?NameValueCollection();foreach?(var?httpContent?in?provider.Contents) {var?formFileName?=?httpContent.Headers.ContentDisposition?.FileName?.Trim('\"');var?formContentType?=?httpContent.Headers?.ContentType?.ToString();if?(!string.IsNullOrEmpty(formFileName)?&&?!string.IsNullOrEmpty(formContentType)){//文件數據using?(var?fileStream?=?new?FileStream(root,?FileMode.Create)){await?httpContent.CopyToAsync(fileStream);}}else{//表單參數var?formFieldName?=?httpContent.Headers.ContentDisposition.Name;var?formFieldValue?=?await?httpContent.ReadAsStringAsync();formData.Add(formFieldName,?formFieldValue);} }.NET Core Web APi FormData文件上傳
HTML和腳本在上述已經提供,這里我們只需關注APi獲取即可。在.NET Core中沒有專門提供獲取FormData數據的APi,那么我們是如何獲取的呢?找了找網上資料,發現大部分是來自廣告網站CSDN,不過這些文章都是轉載的博客園,都是如下這樣獲取
[Route("api/[controller]/[action]")] [ApiController] public?class?UploadController?:?ControllerBase {public?IActionResult?Upload(){var?files?=?Request.Form.Files;return?Ok();} }如上也沒問題,我能說你這思路還停留在.NET Web APi嗎,啥年代了,還通過請求上下文去獲取,.NET Core靈活綁定機制使用起來它不香嗎,通過如下直接綁定豈不完事
此時有的童鞋又有疑問了,上傳不僅僅包括文件還包括參數,比如上述還有標題,那該如何是好,.NET Core的強類型綁定機制它不香嗎,如下定義強類型:
public?class?ExampleUpload {public?string?Title?{?get;?set;?}public?List<IFormFile>?Files?{?get;?set;?} }注意:綁定參數時一定要使用[FromForm],否則將出現請求415,同時也要將前端Ajax FormData文件的參數名和強類型參數名一致。
[Route("api/[controller]/[action]")] [ApiController] public?class?UploadController?:?ControllerBase {public?IActionResult?Upload([FromForm]ExampleUpload?example){return?Ok();} }主要發現網上一部分資料對于利用FormData上傳文件在利用.NET Core接收參數時姿勢不是很正確,故而才有此文,在.NET Core中參數的綁定已完全不需要借助請求上下文來獲取,其綁定機制靈活且強大
總結
以上是生活随笔為你收集整理的.NET和.NET Core Web APi FormData多文件上传的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 联通定时休眠5G基站 戳破皇帝的新衣
- 下一篇: Azure DevOps+Docker+