如何在 .NET Core WebApi 中处理 MultipartFormDataContent 中的文件

news2024/11/22 13:35:06

 

问题描述#

上图示例展示了用户通过 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 内容,尤其是文件类型。如果前后端都能以统一的数据格式来进行交互,自然也就不会出现上述所说的这种问题,潜在的风险自然也就变小了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/869002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ELK常见部署架构以及出现的问题及解决方案

ELK常见部署架构以及出现的问题及解决方案 ELK 已经成为目前最流行的集中式日志解决方案,它主要是由Beats 、Logstash 、Elasticsearch 、 Kibana 等组件组成,来共同完成实时日志的收集,存储,展示等一站式的解决方案。本文将会介…

无情被裁的后续来了

关注、星标公众号,直达精彩内容 来源:技术让梦想更伟大作者:不生气 大家好,给大家分享一个案例,收集好证据,劳动仲裁吧 ,裁员时候老板打感情牌,员工呢坚持付出就得回报按照程序来。…

Zabbix 6.0 监控

文章目录 一、Zabbix简介1)zabbix 是什么?2)zabbix 监控原理3)Zabbix 6.0 新特性1、Zabbix server高可用防止硬件故障或计划维护期的停机2、Zabbix 6.0 LTS新增Kubernetes监控功能,可以在Kubernetes系统从多个维度采集…

【计算机视觉|生成对抗】用深度卷积生成对抗网络进行无监督表示学习(DCGAN)

本系列博文为深度学习/计算机视觉论文笔记,转载请注明出处 标题:Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks 链接:[1511.06434] Unsupervised Representation Learning with Deep Conv…

python——案例18:判断该元素是否在列表中

案例18:判断该元素是否在列表中test_list[10,-8,25.6,88,0,4]print("查看88是否在列表里面:")for i in test_list:if(i88):print("存在") print("查看88是否在列表中:") if(88 in test_list):print("存在…

Scractch3.0_Arduino_ESP32_学习随记_WIFI一键配网web(五)

WIFI一键配网web 目的器材程序联系我们 目的 使用手机为C02一键配网 器材 硬件: 齐护机器人C02 购买地址 软件: scratch3.0 下载地址:官网下载 程序 程序如下图所示: 当程序上载完成后使用手机连接WIFI名为qdprobot的网络,密码为12345678。连接后会自动弹出配网的网页。…

特征选择 | 变量重要性衡量

特征选择 | 变量重要性衡量 目录 特征选择 | 变量重要性衡量写在前面常规方法存在问题解决策略参考资料 写在前面 特征选择是预测模型构建的关键步骤,旨在1)降低数据维度,减少计算量;2)剔除一些无关或冗余变量&#xf…

【uniapp】uniapp自动导入自定义组件和设置分包:

文章目录 一、自动导入自定义组件:二、设置分包和预加载: 一、自动导入自定义组件: 【Volar 官网】https://github.com/vuejs/language-tools 二、设置分包和预加载: 【官方文档】https://uniapp.dcloud.net.cn/collocation…

无涯教程-Perl - ord函数

描述 此函数返回EXPR指定的字符的ASCII数值,如果省略则返回$_。例如,ord(A)返回值为65。 语法 以下是此函数的简单语法- ord EXPRord返回值 该函数返回整数。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl -wprint("ord() ", ord(G), "\n"…

初出茅庐的小李博客之认识编码器

编码器是什么: 一种将角位移或者角速度转换成一连串电数字脉冲的旋转式传感器,我们可以通过编码器测量到底位移或者速度信息。编码器通常由一个旋转部分和一个固定部分组成,旋转部分随着被测量的物体进行旋转,固定部分则保持不动…

大数据-玩转数据-Redis 安装与使用

一、说明 大多数企业都是基于Linux服务器来部署项目,而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis. 此处选择的Linux版本为CentOS 7. Redis的官方网站地址:http://download.redis.io/releases 二、下载 m…

PG常用SQL

数据库 创建数据库 PostgreSQL 创建数据库可以用以下三种方式: 1、使用 CREATE DATABASE SQL 语句来创建。2、使用 createdb 命令来创建。3、使用 pgAdmin 工具。 CREATE DATABASE 创建数据库 CREATE DATABASE 命令需要在 PostgreSQL 命令窗口来执行&#xff0…

Redis安装和配置(Linux)

一、安装准备 VMware虚拟机准备: https://www.vmware.com/cn/products/workstation-pro.html Centos7.0准备: https://www.centos.org/ 二、安装 安装好VMware以后,进入VMware,然后创建新的虚拟机 创建好虚拟机以后,进行安装C…

Fast SAM与YOLOV8检测模型一起使用实现实例分割以及指定物体分割

Fast SAM与YOLOV8检测模型一起使用 部分源代码在结尾处可获取 晓理紫 1 使用场景 实例分割数据集的获取要比检测数据的获取更加困难,在已有检测模型不想从新标注分割数据进行训练但是又想获取相关物体的mask信息以便从像素级别对物体进行操作,这时就可以…

Vue实现详细界面里面有一个列表

目录 Vue实现详细界面里面有一个列表 理一下思路: 效果如下: 1、 主页面正常写 2、详细界面(重点) 3、详细界面里面的列表(重点) 要点: Vue实现详细界面里面有一个列表 理一下思路: 1、首先需要这条数据的主键id&#xff…

包装类+初识泛型

目录 1 .包装类 1.1 基本数据类型对应的包装类 1.2.1装箱 ​1.2.2拆箱 2.初识泛型 2.1什么是泛型 2.2泛型类 2.3裸类型 2.4泛型的上界 2.5泛型方法 1 .包装类 基本数据类型所对应的类类型 在 Java 中,由于基本类型不是继承自 Object ,为了在泛型…

LeetCode150道面试经典题--同构字符串(简单)

1.题目 给定两个字符串 s 和 t ,判断它们是否是同构的。如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上&#xff0c…

2022年06月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;倒序输出 依次输入4个整数a、b、c、d,将他们倒序输出&#xff0c;即依次输出d、c、b、a这4个数。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 输入 一行4个整数a、b、c、d&#xff0c;以空格分隔。 0 < a,b,c,d < 108 输出 一行4个整数d、c、…

11.集群调度

文章目录 集群调度调度约束list-watc机制的概念pod的创建流程 调度过程Scheduler 作用预选策略优选策略指定调度节点nodeNamenodeSelector 亲和性node亲和pod亲和pod反亲和 污点&#xff08;Taint&#xff09;和容忍&#xff08;Tolerations&#xff09;污点(Taint)容忍(Tolera…

QT的界面切换

QT的界面切换 步骤一: 创建一个新的 ui 界面