Issue
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.
Solution
It isn't working because you're mixing JSON and traditional
<form>data.- Some background info:
- In "normal" HTML, without scripting or AJAX, a
<form>can bePOST-submitted as eitherapplication/x-www-form-urlencodedor asmultipart/form-data.application/x-www-form-urlencodedis an almost-human-readable textual representation of every key+value pair. e.g.key1=value1&key2=value2.multipart/form-datais a binary encoding. You need to use this option when posting files from an<input type="file">.
- With JavaScript-initiated HTTP requests (using
fetchorXMLHttpRequest) it is commonplace to POST data as JSON (application/json) instead of either of the 2<form>encodings.- Angular's
HttpClientusesfetchinternally. - It would be nice if
<form>could be used to submit JSON too, without any scripting; it doesn't, oh well.
- Angular's
- In "normal" HTML, without scripting or AJAX, a
- Some background info:
In your case specifically, your
Itemsis aList<...>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
Itemsin a way compatible with ASP.NET's form model-binding syntax.- Specifically, each discrete value has its own form name, and each list element is referenced by a 0-based incremental index.
In your case, the keys/names for
Itemswill 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"- Note that ASP.NET (all versions) always require collection indexers to be 0-based and have no gaps between indexes, otherwise the
List<>property will benullor empty and there won't be any warnings or errors (which is annoying).
- Note that ASP.NET (all versions) always require collection indexers to be 0-based and have no gaps between indexes, otherwise the
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 );
Alternative quick-fix workaround "solution"
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 );
}
}
Answered By - Dai

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.