asp.net core webapi文件上傳

最近開發一個新項目,使用了asp.net core 2.0,採用webapi開發後臺,postgresql爲數據庫。最早來的問題就是上傳文件的問題。html


POST文件的一些坑

使用默認模板建立webapi的controller後,post請求,默認有前端

// POST api/values
        [HttpPost]
        public void Post([FromBody]string value)
        {
        }

請求使用了[FromBody]標記,用來指示用請求體裏得到數據。web

對於文件上傳請求,直接在這個Post函數裏使用Request.Form.Files是不行的,沒法成功路由。
典型上傳,須要設置前端發送的請求Content-Typemultipart/form-data,而後在控制器類加上特性修飾:sql

[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.Formjson

注意,不少地方寫了可使用IFormFile,直接寫成c#

// POST: api/File
        [HttpPost]
        public Task<ActionResult> Post(IFormFile file)

實際測試沒有辦法獲取到對象,file常態爲null,或者是我方法不對。api

而後就能夠在post方法裏面使用files.Files來枚舉文件了,每一個文件都是一個IFormFile對象,能夠靈活使用FileName, Name,Length等經常使用屬性。固然,咱們也能夠不帶參數:app

// POST: api/File
        [HttpPost]
        public Task<ActionResult> Post()

直接使用Request.Form.Files得到文件數據。asp.net

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發送,如今是直接類型識別...

BUT

他喵的還在傳文件啊,原地踏步啊,三年了難受!

相關文章
相關標籤/搜索