最近开发一个新项目,使用了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发送,现在是直接类型识别...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。