传递对象的 FormData 项数组 angular

Pass FormData Item array of object 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)
    {

    }

其他都很好我收到了除了物品以外的所有东西。项目始终为 0。

  • 它不起作用,因为你混合了JSON和传统的<form>数据

    • 一些背景信息:
      • 在“正常”HTML 中,没有脚本或 AJAX,<form> 可以 POST 提交为 application/x-www-form-urlencodedmultipart/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 数组表单项,每个值一个。

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

      • 具体来说,每个离散值都有自己的形式名称,每个列表元素都由一个从 0 开始的增量索引引用。
    • 在您的情况下,Items 的 keys/names 将类似于:

      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 );
    }
}