asp.net core webapi檔案上傳功能的實現
最近開發一個新專案,使用了asp.net core 2.0,採用webapi開發後臺,postgresql為資料庫。最先來的問題就是上傳檔案的問題。
POST檔案的一些坑
使用預設模板建立webapi的controller後,post請求,預設有
// POST api/values [HttpPost] public void Post([FromBody]string value) { }
請求使用了[FromBody]
標記,用來指示用請求體裡獲得資料。
對於檔案上傳請求,直接在這個Post函式裡使用Request.Form.Files
是不行的,無法成功路由。
典型上傳,需要設定前端傳送的請求Content-Type
multipart/form-data
,然後在控制器類加上特性修飾:
[Produces("application/json")] [Consumes("application/json","multipart/form-data")]//此處為新增 [Route("api/[controller]")] public class FileController : Controller
指示該controller能夠接受multipart/form-data
形式的資料。對應的,修改post的程式碼如下:
// POST: api/File [HttpPost] public Task<ActionResult> Post(IFormCollection files)
這裡需要注意,使用的是IFormCollection。這是IForm的型別集合,實際上就是Request.Form
。
注意,很多地方寫了可以使用IFormFile,直接寫成
// POST: api/File [HttpPost] public Task<ActionResult> Post(IFormFile file)
實際測試沒有辦法獲取到物件,file常態為null,或者是我方法不對。
然後就可以在post方法裡面使用files.Files來列舉檔案了,每個檔案都是一個IFormFile物件,可以靈活使用FileName,Name,Length等常用屬性。當然,我們也可以不帶引數:
// POST: api/File [HttpPost] public Task<ActionResult> Post()
直接使用Request.Form.Files獲得檔案資料。
P.S. 對於IFormFile,與System.IO.File
物件不同,IFormFile缺少很多方法,只提供OpenReadStream()
方法,該方法返回一個stream物件。很多讀檔案的API都可以接受stream作為FilePath的替代。
同時上傳其他資料
一般的檔案上傳請求,不單上傳檔案資料,通常還需要上傳其他檔案資訊資料(比如檔案型別,上傳者等等)。修改一下post方法,改成這樣:
[HttpPost] public Task<ActionResult> Post([FromBody]string type,IFormCollection files)
將type都打包進請求,再次傳送。發現......type是null。
MSDN說了,The reason for this rule is that the request body might be stored in a non-buffered stream that can only be read once.
所以,[FromBody]只能加一個,但是我這確實也只加了一個,有問題?很明顯,那個IFormCollection也是預設通過[FromBody]解析的,所以正確的方法是不加[FromBody]了。
[HttpPost] public Task<ActionResult> Post(string type,IFormCollection files)
後記
回想起當年做WebService的時候,上傳檔案寫的
多平臺上傳
,感觸頗多,以前是轉碼到base64,通過string傳送,現在是直接型別識別...
到此這篇關於asp.net core webapi檔案上傳的文章就介紹到這了,更多相關asp.net core webapi檔案上傳內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!