传递对象角度的FormData Item数组
Posted
技术标签:
【中文标题】传递对象角度的FormData Item数组【英文标题】:Pass FormData Item array of object angular 【发布时间】:2022-01-11 10:45:04 【问题描述】:如何将 FormData 传递给 api,其中包含对象数组?
我正在尝试这样
这是请求的负载 如何在 .net core c# Api 中获取所有包含其他数据的项目?
public class BackgroundCheckParam
public Guid EmpId get; set;
public List<BackgroundChecksResults> Items get; set;
public IFormFile ResultPdf get; set;
public IFormFile DisclosurePdf get; set;
public DateTime CompleteDate get; set;
public class BackgroundChecksResults
public string Type get; set;
public string Result get; set;
public ResponseResult AddBackgroundCheck([FromForm] BackgroundCheckParam data)
其他都很好,除了物品,我什么都收到了。项目始终为 0。
【问题讨论】:
使用 Angular 的HttpClient
。警告:它会强制你使用 RxJS,它的学习曲线非常陡峭。
已经使用 Angular 的 HttpClient 来创建上面的有效载荷。只需要 c# 帮助我如何以列表的形式访问项目。
它不起作用,因为您正在混合 JSON 和 <form>
数据。这不是 ASP.NET Core 的错。您需要更改 Angular/TypeScript 以使用 ASP.NET 的 List FormData 名称值,而不是 JSON。
这意味着我们不能在 FormData 中传递这样的项目?
没错。要么只使用 JSON,要么只使用 URLSearchParams
(application/x-www-form-urlencoded
) 主体。
【参考方案1】:
它不起作用,因为您正在混合 JSON 和传统的 <form>
数据。
<form>
可以POST
提交为application/x-www-form-urlencoded
或multipart/form-data
。
application/x-www-form-urlencoded
是每个键+值对的几乎人类可读的文本表示。例如key1=value1&key2=value2
。
multipart/form-data
是二进制编码。从<input type="file">
发布文件时,您需要使用此选项。
对于 javascript 发起的 HTTP 请求(使用 fetch
或 XMLHttpRequest
),通常将数据以 JSON (application/json
) 形式发布,而不是使用两种 <form>
编码中的任何一种。
Angular 的HttpClient
在内部使用fetch
。
如果<form>
也可以用于提交JSON,而不需要任何脚本,那就太好了;它没有,哦,好吧。
具体而言,您的Items
是一个List<...>
,当它应该作为多个表单项发送时,它被表示为单个表单项中的 JSON 数组,每个值一个。
解决方案是以与 ASP.NET 的表单模型绑定语法兼容的方式表示 Items
。
在您的情况下,Items
的键/名称将类似于:
Items[0].Type = "Background"
Items[0].Result = "Pass"
Items[1].Type = "Foreground"
Items[1].Result = "Fail"
Items[2].Type = "Middleground"
Items[2].Result = "Compromise"
请注意,ASP.NET(所有版本)始终要求集合索引器从 0 开始,并且索引之间没有间隙,否则 List<>
属性将为 null
或为空,并且不会出现任何警告或错误(很烦人)。
所以你应该有这样的东西:
// * Use `URLSearchParams` for `application/x-www-form-urlencoded`.
// * Use `FormData` for `multipart/form-data`.
const resultPdfFile = inputElement1.files[0];
const disclosurePdf = inputElement2.files[0];
const formValues = new FormData();
formValues.append( "EmpId" , "fckgw-rhqq2-yxrkt-8tg6w-2b7q8" );
formValues.append( "ResultPdf" , resultPdfFile );
formValues.append( "DisclosurePdf", disclosurePdf );
formValues.append( "CompleteDate" , "2021-12-01" );
for( let i = 0; i < items.length; i++ )
const keyPrefix = "Items[" + i.toString() + "].";
formValues.append( keyPrefix + "Type" , items[i].type ); // e.g. "Items[0].Type"
formValues.append( keyPrefix + "Result", items[i].result );
await postRequest( formValues );
替代快速修复解决方法“解决方案”
在您的 ASP.NET 代码中,忽略您的 BackgroundCheckParam data
操作参数的 Items
成员和来自 Request.Form
的 JSON 解码 Items
:
public ResponseResult AddBackgroundCheck([FromForm] BackgroundCheckParam data)
IReadOnlyList<BackgroundChecksResults> items;
String formList = this.Request.Form["Items"];
items = JsonConvert.DeserializeObject< List<BackgroundChecksResults> >( formList );
【讨论】:
以上是关于传递对象角度的FormData Item数组的主要内容,如果未能解决你的问题,请参考以下文章