zoukankan      html  css  js  c++  java
  • 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-Typemultipart/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发送,现在是直接类型识别...

    BUT

    他喵的还在传文件啊,原地踏步啊,三年了难受!

  • 相关阅读:
    wcf 配置
    一般处理程序问题重命名后问题
    jQuery取得select选择的文本与值
    C# 读取excel
    ajax 跨域问题
    java转义字符
    oracle日期时间的加减法
    在MyEclipse中,jsp文件输入中文,文件不能保存
    转自JavaEye Oracle函数大全
    转Oracle数据类型及存储方式【F】
  • 原文地址:https://www.cnblogs.com/podolski/p/7795168.html
Copyright © 2011-2022 走看看