Home > database >  Passing a file from React/TypeScript to C# API causes error: "The JSON value could not be conve
Passing a file from React/TypeScript to C# API causes error: "The JSON value could not be conve

Time:10-17

I am trying to pass an img file from a frontend written in React/Typescript to an API written in C#.

These are the functions that handle uploading a photo and the upload of the state to the C# API, using Axios:

const handleImageUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
        
        const files = event.target.files as FileList
        const file = files[0] as File

        setRecipeData((prev) => {
            return {...prev, RecipePhoto: file}
        })
    }
    const handleRecipeUpload = () => {
        
        axios.post('https://localhost:7104/api/Recipe/Post', recipeData)
        .then((response) => {
            console.log(response)
        })
        .catch((error) => {
            console.log(error)
            console.log(JSON.stringify(error.response.data.errors));
        })
    }

Here is my controller in C#

        [HttpPost]
        [Route("Post")]
        public async Task<IActionResult> PostRecipeAsync(PostRecipeDto postRecipeDto)
        {
            return Ok(await _postRecipeServices.PostRecipeService(postRecipeDto));
        }

And the model for the Dto:

    public class PostRecipeDto
    {
        public string? Name { get; set; }
        public string? Description { get; set; }
        public string? Country { get; set; }
        public string? IngridientList { get; set; }
        public int CookingTimeInMins { get; set; }
        public byte[]? RecipePhoto { get; set; }
    }

The error that I am getting in browser console, while trying to upload is:

{"postRecipeDto":["The postRecipeDto field is required."],"$.RecipePhoto":["The JSON value could not be converted to System.Byte[]. Path: $.RecipePhoto | LineNumber: 0 | BytePositionInLine: 155."]}

So I guess, I am either passing the file in a wrong way or the model is incorrect and shouldn't be byte[].

I would greatly appeciate any advice on what would be the optimal way to fix this!

CodePudding user response:

You can change your handleRecipeUpload method to something like below

const handleRecipeUpload = () => {
     const formData = new FormData();
formData.append('RecipePhoto', recipeData.RecipePhoto);
// append all other properties of `recipeData`
.
.
.
const config = {
  headers: {
    'content-type': 'multipart/form-data',
  },
};
    axios.post('https://localhost:7104/api/Recipe/Post', formData, config)
    .then((response) => {
        console.log(response)
    })
    .catch((error) => {
        console.log(error)
        console.log(JSON.stringify(error.response.data.errors));
    })
}

On the C# side change class PostRecipeDto as below --

public class PostRecipeDto
{
    public string? Name { get; set; }
    public string? Description { get; set; }
    public string? Country { get; set; }
    public string? IngridientList { get; set; }
    public int CookingTimeInMins { get; set; }
    public IFormFile? RecipePhoto { get; set; }
}

And to get bytes from IFormFile you can reference the below link --

https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.iformfile?view=aspnetcore-6.0

  • Related