skip to Main Content

I have created a C# controller to receive files i pass from my client side. I get a error called "The files field is required" and cannot seem to fix it. Please note that I am new to C# and have only worked with JS.

Following is my controller

public class FileUploadController : ControllerBase
{
    [HttpPost]
    [Route("fileupload")]
    public async Task<IActionResult> PackIt(List<IFormFile> files)
    {
        if (files == null || files.Count == 0)
        {
            return BadRequest("No files uploaded.");
        }

        return Ok(new { message = "Files received successfully." });
    }
}

And following is my client side code

async function sendLogicFiles(fileHandles: FileSystemFileHandle[]) {
  try {
    const formData = new FormData()
    fileHandles.forEach(async (file, index) => {
      const fileHandle = fileHandles[index]
      const _file = await fileHandle.getFile()
      formData.append(`files[${index}]`, _file)
    })
    const response = await fetch('fileupload', {
      method: 'POST',
      body: formData,
    })
    if (!response.ok) {
      throw new Error('Network response was not ok ' + response.statusText)
    }
    const responseData = await response.json()
    console.log('Success:', responseData)
  } catch (error) {
    console.error('Error:', error)
  }
}

When I execute the code, I get the following error message for API response

{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "errors": {
        "files": [
            "The files field is required."
        ]
    },
    "traceId": "00-2073e137b176760a1c75cd95b8a542dc-6f64030c375117eb-00"
}

How can I fix it? Or Am I in the right track to do this?

3

Answers


  1. Try to use formData.append('files', _file) without index and add [FromForm] attribute.

    [HttpPost]
    [Route("fileupload")]
    public async Task<IActionResult> PackIt([FromForm] List<IFormFile> files)
    {
        if (files == null || files.Count == 0)
        {
            return BadRequest("No files uploaded.");
        }
    
        return Ok(new { message = "Files received successfully." });
    }
    
    Login or Signup to reply.
  2. @CraZyDroiD
    If you want to send file to controller, you should create a model first.

    public class FileModel
    {
        public int Id { get; set; }
        
        [Display(Name = "image")]
        public IFormFile? image { get; set; }
    }
    

    And pass this model to your controller’s action.

    public async Task<IActionResult> Create([Bind("Id,image")] FileModel model)
    {
        T_File t_File = new T_File();
        if (ModelState.IsValid)
        {
            var path = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "wwwroot/Upload/Image"));
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            if (model.image != null)
            {
                using (var fileStream = new FileStream(Path.Combine(path, model.image.FileName), FileMode.Create))
                {
                    await model.image.CopyToAsync(fileStream);
                }
            }
            t_File.staff_id = currentUser.Id;
            t_File.image = "/Upload/Image/" + model.image.FileName;
    
            _context.Add(t_File);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(model);
    }
    

    And please keep in mind to add enctype="multipart/form-data" to form tag in the view.
    Hope it can be helpful.

    Login or Signup to reply.
  3. I have had a similar issue before and I resolved it by using "for…of" loop. From experience using the "foreach" loop in JavaScript does not wait for the ‘await’ before moving to the next iteration in an asynchronous code. You can read this https://www.squash.io/how-to-use-async-await-with-a-foreach-loop-in-javascript/ for more understanding.

    In your sendLogicFiles function you can replace the foreach with the code below

    for (const fileHandle of fileHandles) {
      const _file = await fileHandle.getFile();
      formData.append('files', _file); 
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search