I editted the whole question because it was very long and confusing.
I was sending all data from my forms as a stringified JSON, but now I need to append a file, so I can no longer do this. How do I send my form data from React to an ASP.NET Core API in a format that allows appending files?
I have several forms working perfectly: I send the data using fetch from React and receive it correctly as body in my ASP.NET Core API.
However, I need to send files now, and I don't know how to append them since I am just sending all of my content in a strinfified JSON.
fetch("localhost/api/test", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}).then(result => result.json()).then(
(result) => {
console.log(result);
}
);
I tried sending a FormData object built like this instead of the JSON.stringify(body).
let formData = new FormData();
for (var property in body) {
formData.append(property, body[property]);
}
But when I send this object instead of the stringified JSON I always get null for all the values in ASP.NET Core.
I also tried sending this:
URLSearchParams(data)
And this:
let formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
And I tried different combinations of headers with every type of data encoding:
'Content-Type': 'multipart/formdata''Content-Type': 'application/json''Content-Type': 'application/x-www-form-urlencoded'I also tried getting the data from ASP.NET with both [FromBody] and [FromForm].
I think I have tried every possible combination of all the options I have explained above, with no result. I always get null values in my API.
Edit:
Right now, I am not even trying to send a file. I am trying to successfully send common data in the proper format before trying to attach a file. I don't know if I should change the title of the question.
This is my API code:
[HttpPost]
[Route("login")]
public object Login([FromBody] Credentials cred)
{
// check credentials
return CustomResult.Ok;
}
The class Credentials:
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
The object body from React looks like this:
{
username: "user",
password: "pass"
}
My whole question was a mess and, in my case, the problem was the for loop. However, I will try to explain clearly what I needed because there is a lot of missleading information online about how to submit a form to an API with React.
In the backend, accept POST petitions and get the data with FromForm. If you need to use credentials, it is probably better to pass them through headers instead of putting them as hidden inputs inside every single form.
[HttpPost]
[Route("test")]
public object Test([FromHeader] string token, [FromForm] MyDataClass data)
{
// check token
// do something with data
return CustomResult.Ok;
}
If you bind an object, the properties must have the same name as the ones you are sending from the frontend and must have a public setter.
public class MyDataClass
{
public string SomeInfo { get; set; }
public string SomeOtherInfo { get; set; }
}
Send the data as FormData. To do this, you can follow this tutorial. That way, you won't need to worry about handling input changes and formatting your data before submitting it.
However, if your data is already in a plain JavaScript object, you can transform it in a FormData as shown below.
let formData = new FormData();
Object.keys(data).forEach(function (key) {
formData.append(key, data[key]);
});
Nonetheless, this is very basic and if you have a complex object (with arrays, nested objects, etc) you will need to handle it differently.
Finally, I used fetch to call my API. If you use it, it is important to NOT set the Content-Type header, because you will be overwritting the one that fetch automatically chooses for you, which will be the right one in most cases.
fetch("localhost/api/test", {
method: 'POST',
headers: {
'Token': "dummy-token"
// DON'T overwrite Content-Type header
},
body: formData
}).then(result => result.json()).then(
(result) => {
console.log(result);
}
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With