传递对象 Angular 的 FormData Item 数组

Fai*_*sal 2 c# form-data .net-core angular

如何将 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)
    {

    }
Run Code Online (Sandbox Code Playgroud)

其他一切都很好,我收到了除物品之外的所有物品。项目始终为 0。

Dai*_*Dai 6

  • 它不起作用,因为您正在混合 JSON 和传统<form>数据

    • 一些背景信息:
      • 在“普通”HTML 中,无需脚本或 AJAX,a<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 请求(使用fetchXMLHttpRequest),通常将数据 POST 为 JSON ( application/json),而不是这 2 种<form>编码中的任何一种。
        • Angular在内部HttpClient使用fetch
        • <form>如果也可以用来提交 JSON,而不需要任何脚本,那就太好了;事实并非如此,哦,好吧。
  • 具体来说,在您的情况下,您的Items数据List<...>在单个表单项中表示为 JSON 数组,而应将其作为多个表单项(每个值一个)发送。

    • Items解决方案是以与 ASP.NET 的表单模型绑定语法兼容的方式表示

      • 具体来说,每个离散值都有自己的表单名称,每个列表元素都由从 0 开始的增量索引引用。
    • 在您的情况下,键/名称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" 
      
      Run Code Online (Sandbox Code Playgroud)
      • 请注意,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 );
Run Code Online (Sandbox Code Playgroud)

替代快速修复解决方法“解决方案”

在您的 ASP.NET 代码中,忽略操作参数Items的成员并从BackgroundCheckParam data以下位置进行 JSON 解码:ItemsRequest.Form

public ResponseResult AddBackgroundCheck([FromForm] BackgroundCheckParam data)
{
    IReadOnlyList<BackgroundChecksResults> items;
    {
        String formList = this.Request.Form["Items"];

        items = JsonConvert.DeserializeObject< List<BackgroundChecksResults> >( formList );
    }
}
Run Code Online (Sandbox Code Playgroud)