How can I pass FormData to api with array of obejcts inside?
i am trying like this
this is the payload of request how can i get all items with other data i .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)
{
}
All other is fine I am receiving everything but Items. Items are always 0.
It isn't working because you're mixing JSON and traditional <form>
data.
<form>
can be POST
-submitted as either application/x-www-form-urlencoded
or as multipart/form-data
.
application/x-www-form-urlencoded
is an almost-human-readable textual representation of every key+value pair. e.g. key1=value1&key2=value2
.multipart/form-data
is a binary encoding. You need to use this option when posting files from an <input type="file">
.fetch
or XMLHttpRequest
) it is commonplace to POST data as JSON (application/json
) instead of either of the 2 <form>
encodings.
HttpClient
uses fetch
internally.<form>
could be used to submit JSON too, without any scripting; it doesn't, oh well.In your case specifically, your Items
is a List<...>
being represented as a JSON array in a single form item when it should be sent as multiple form items, one for each value.
The solution is to represent Items
in a way compatible with ASP.NET's form model-binding syntax.
In your case, the keys/names for Items
will be like:
Items[0].Type = "Background"
Items[0].Result = "Pass"
Items[1].Type = "Foreground"
Items[1].Result = "Fail"
Items[2].Type = "Middleground"
Items[2].Result = "Compromise"
List<>
property will be null
or empty and there won't be any warnings or errors (which is annoying).So you should have something like this:
// * 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 );
In your ASP.NET code, ignore the Items
member of your BackgroundCheckParam data
action parameter and JSON-decode Items
from Request.Form
:
public ResponseResult AddBackgroundCheck([FromForm] BackgroundCheckParam data)
{
IReadOnlyList<BackgroundChecksResults> items;
{
String formList = this.Request.Form["Items"];
items = JsonConvert.DeserializeObject< List<BackgroundChecksResults> >( formList );
}
}