5

I'm trying to post FormData including both a File and a Collection.

This is my Model:

public class Content
{
    public string Name { get; set; }
    public string Link { get; set; }
}
public class Model
{
    public IEnumerable<Content> Contents { get; set; }
    public IFormFile File { get; set; }
}

This is my action:

[HttpPost]
public async Task InsertAsync([FromForm]Model dataPost)
{
    await _services.Create(dataPost);
}

My FormData in JavaScript is:

const formData = new FormData();
formData.append("File", myFile, "image.jpg")
formData.append("Contents", arrayOfContent)

And here is the header:

'Content-Type': `multipart/form-data`

The "File" is working fine, but the "Content" is always null.

Where am I going wrong? Thank you!

Tony Ngo
  • 19,166
  • 4
  • 38
  • 60
mikenlanggio
  • 1,122
  • 1
  • 7
  • 27
  • were you able to solve this issue? I have the exact same one, only that the accepted answer didn't help me solve it. thanks! – ajzbrun Dec 26 '22 at 19:00

2 Answers2

4

For test I used the following arrayOfContent:

var arrayOfContent = [];
arrayOfContent.push({ name: 'test', link: 'test.com' });
arrayOfContent.push({ name: 'test2', link: 'test2.com' });

And I used a for loop to append the array to the form data:

for (var i = 0; i < arrayOfContent.length; i++) {
    formData.append("Contents[" + i + "].Name", arrayOfContent[i].name);
    formData.append("Contents[" + i + "].Link", arrayOfContent[i].link);
}

And I in Visual Studio I can see that it can bind it:

enter image description here

hujtomi
  • 1,540
  • 2
  • 17
  • 23
  • There is a similar question here: https://stackoverflow.com/questions/6243051/how-to-pass-an-array-within-a-query-string I wrote my answer based on this. – hujtomi Sep 01 '19 at 16:12
1

You need to convert your array to JSON string in ajax submit code like this

const formData = new FormData();
formData.append("File", myFile, "image.jpg")
formData.append("Contents",  JSON.stringify(arrayOfContent))

Then deserialize in your controller

Tony Ngo
  • 19,166
  • 4
  • 38
  • 60