如何在 .NET Core WebApi 中处理 MultipartFormDataContent 中的文件
在上一篇文章(如何在 .NET Core WebApi 中处理 MultipartFormDataContent)中,我们有描述过如何以最简单的方式在 .NET Core WebApi 中处理 MultipartFormDataContent 。基于框架层面的封装,我们可以快速的从 Request.Form 中分别拿到文件内容和文本内容,但是这些默认的解析方式都是建立在前后端以标准的数据格式来进行构建和解析。
问题描述

上图示例展示了用户通过 IOS 客户端发送请求时,对应后端接口接收到的 Request 内容。从请求内容的整体结果,我们可以看出这是一个 multipart/form-data 的数据格式,由于这种数据是由多个 multipart section 组成,所以我们可以看出在这个请求体中,是包含3个 section ,name 值分别为 Agree,CultureCode,FingerSignature,每个 section 都会包含一个 Content-Disposition 字段,前面两个 section都是普通的数据格式,最后一个是图片类型的数据。当后端接口接收到这样一个请求体时,尝试使用 Request.Form.Files 的方式来获取目标文件时,发现无法获取 FingerSignature 对应的文件内容。
问题分析
通过和客户沟通,了解到FingerSignature 对应的文件是会被一起放到请求体中传给后端,客户表示前端APP这一块的逻辑在后端还没有升级成 ASP.NET Core(处于 Framework 阶段)的时候是可以正常工作的。通过查看ASP.NET Core 中对 Request.Form 的赋值逻辑: FormFeature 实现,找到了如下逻辑函数:

通过源码的逻辑,我们可以看出,只有当前的 section 对应的 Content-Disposition 同时包含 form-data 和 fileName (或 fileNameStar),才会被作为文件来处理(示例:form-data; name="FingerSignature"; fileName=”xxxx.jpeg”),否则并不会把当起的 Section 添加到 Request.Form.Files 中。此时结合上面获取的请求内容,定位到 FingerSignature 部分的 Content-Disposition 中由于缺少 fileName 字段导致后端无法解析到对应文件为该issue 的 Root Cause。
解决方案
由于前端 APP 已经发布多个版本,所以让前端来补全这个字段显然不是一种稳妥的修复方案,因此后端需要做一个兼容性处理。当遇到这种不是标准格式的文件内容,需要通过 MultipartReader 对象来处理 MultipartFormDataContent 对应的 Section 内容(实际上 Request.Form.Files 底层逻辑就是通过 MultipartReader 来依次解析每个 Section 内容)。这里实现了一个方法来获取当前 MultipartFormDataContent 中的所有文件:

在这个方法中有2个细节地方需要注意。
- 默认情况下,Request.Body 中的内容只允许读取一次,所以我们需要在使用这个方法的路由地方启用 EnableBuffering 设置,这里可以自定义一个 Filter 来复用这种特性:

- 因为对 Request.Body开启 EnableBuffering 了,所以在调用 ReadFilesAsyns 方法的时候,不确定此时 Body 中的 Stream起始位置为 0。所以我们需要在读取 Body 之前和之后通过 Seek 方法将 Stream的 Position 重置归 0。
优化建议
从目前的修复方案来讲的话,后端只是提供了一种妥协的修复方案来适配前端的数据不完整,因此感觉比较完善的修复方案是前端在发送 multipart/form-data 的数据时,尽量以标准的方式来构建每个 Section 内容,尤其是文件类型。如果前后端都能以统一的数据格式来进行交互,自然也就不会出现上述所说的这种问题,潜在的风险自然也就变小了。
如何在 .NET Core WebApi 中处理 MultipartFormDataContent 中的文件的更多相关文章
- 如何将dotnet core webapi发布到docker中…
如何将dotnet core webapi发布到docker中 今天想起来撸一下docker,中途还是遇到些问题,但是这些问题都是由于路径什么的导致不正确,在这儿还是记录下操作过程,今天是基于wind ...
- asp.net core webapi处理Post请求中的request payload
request payload的Content-Type实际上是text/plain的,如果请求的 Content-Type 为 application/json,这将导致415 Unsupporte ...
- ASP.NET Core WebAPI实现本地化(单资源文件)
在Startup ConfigureServices 注册本地化所需要的服务AddLocalization和 Configure<RequestLocalizationOptions> p ...
- ASP.NET Core WebAPI中的分析工具MiniProfiler
介绍 作为一个开发人员,你知道如何分析自己开发的Api性能么? 在Visual Studio和Azure中, 我们可以使用Application Insight来监控项目.除此之外我们还可以使用一个免 ...
- ASP.NET Core WebApi 返回统一格式参数(Json 中 Null 替换为空字符串)
相关博文:ASP.NET Core WebApi 返回统一格式参数 业务场景: 统一返回格式参数中,如果包含 Null 值,调用方会不太好处理,需要替换为空字符串,示例: { "respon ...
- Asp.Net Core WebApi中接入Swagger组件(初级)
开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ...
- 如何在启用JWT Token授权的.NET Core WebApi项目中下载文件
背景 前几天,做项目的时候遇到一个文件下载的问题.当前系统是一个前后端分离的项目,前端是一个AngularJs项目, 后端是一个.NET Core WebApi项目.后端的Api项目使用了Jwt To ...
- .NET Core WebApi中实现多态数据绑定
什么是多态数据绑定? 我们都知道在ASP.NET Core WebApi中数据绑定机制(Data Binding)负责绑定请求参数, 通常情况下大部分的数据绑定都能在默认的数据绑定器(Binder)中 ...
- Asp.Net Core WebAPI+PostgreSQL部署在Docker中
PostgreSQL是一个功能强大的开源数据库系统.它支持了大多数的SQL:2008标准的数据类型,包括整型.数值值.布尔型.字节型.字符型.日期型.时间间隔型和时间型,它也支持存储二进制的大对像, ...
- 文章翻译:ABP如何在EF core中添加数据过滤器
原文地址:https://aspnetboilerplate.com/Pages/Documents/Articles%5CHow-To%5Cadd-custom-data-filter-ef-cor ...
随机推荐
- Rstudio R get filename full path
FILENAME=basename(rstudioapi::getActiveDocumentContext()$path) FULLPATH=dirname(rstudioapi::getActiv ...
- git push 报错error: remote unpack failed: error Short read of block
1.解决办法:找管理代码的人给你开权限. 2如果你的push的命令写错的话,也是会出现远端拒绝的提示,所以记得检查自己的push 命令是否正确 另一种明显的权限拒绝的例子: 英语学习:to push ...
- 不同页面的 body设置
由于SPA页面的特性,传统的设置 body 背景色的方法并不通用. 解决方案:利用组件内的路由实现 第一种方式 // 实例创建之前 beforeCreate(){ document.querySele ...
- 解决idea xml文件中的中文注释乱码
今天用idea编译xml文件的时候报错了,打开编译好的xml文件发现是中文乱码问题,按照百度上靠前的办法设置了一下,并没有解决乱码问题,在当前项目中直接设置就是不生效,最后删掉编译好的 target/ ...
- flask orm 操作方法
数据库操作 常用的查询过滤器 过滤器 说明 filter() 把过滤器添加到原查询上,返回一个新查询 filter_by() 把等值过滤器添加到原查询上,返回一个新查询 limit() 使用指定的值限 ...
- 解决 SMTP Error: data not accepted php邮件发送失败的问题
php 发送邮件 出现 SMTP Error: data not accepted 1.正常情况下 都是正常的 但是偶尔 发送失败了 163.com 邮箱发送不了了. 所以去查了下问题所在 在 ...
- JMeter压测脚本实例:单接口
新建测试计划 添加线程组 添加HTTP请求 配置该请求相关参数 1.请求头部信息 ①HTTP请求同级线程组下添加HTTP信息头部管理器 ②填充该请求所需的头部信息 2.请求体 选中之前增加的HTTP请 ...
- Linux下apache日志(按日期存放)分析与状态查看方法
转载网址: https://blog.csdn.net/weixin_42272246/article/details/125602258
- Mybatis数据库驱动
Mybatis数据库驱动 最近在学习mybatis的源码,有一个databaseIdProvider根据不同数据库执行不同sql的功能,我正好有一个mysql还有一个瀚高数据库,就去试了一下,使用如下 ...
- 我们为什么要阅读webpack源码
相信很多人都有这个疑问,为什么要阅读源码,仅仅只是一个打包工具,会用不就行了,一些配置项在官网,或者谷歌查一查不就好了吗,诚然在大部分的时候是这样的,但这样在深入时也会遇到以下几种问题. webpac ...