1

This question might be a duplicate, in that case I would love to get a reading on it, but please check if the duplicate question fits mine. I have tried looking for answers, but have not found any that fits my question correctly.

I have a website built with React served from a .NET Core 2.0 project with a regular Web API generated from the regular Controller web api that is built in to the project. The Web API is set up like this:

[Produces("application/json")]
[Route("api/File")]
public class FileController : Controller
{      
    // POST: api/File
    [HttpPost]
    public ActionResult Post()
    {
        Console.WriteLine(Request);
        return null;
    }

I want to upload Images / PDF files and other file types from a regular input type="file" field.

The code for that can be seen below:

export class Home extends Component {
  render() {
    return <input type = "file"
    onChange = {
      this.handleFileUpload
    }
    />
  }

  handleFileUpload = (event) => {
    var file = event.target.files[0];
    var xhr = new XMLHttpRequest();
    var fd = new FormData();
    xhr.open("POST", 'api/File', true);
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4 && xhr.status == 200) {
        // Every thing ok, file uploaded
        console.log(xhr.responseText); // handle response.
      }
    };
    fd.append("upload_file", file);
    xhr.send(fd);
  }
}

What needs to be implemented in the Post-file-controller part for the correct handling of the file? If I want the file to be uploaded as, say a uint8 array (to be stored).

Every bit of help is appreciated as I am stuck.

2 Answers 2

2

I'm a bit late to the party but if anybody else struggles with this problem: The reason the backend parameter file was null in my case, was because the input name in the frontend must be the same as the method parameter name in the backend.

In your example you chose the input name upload_file

fd.append("upload_file", file);

so the parameter in the backend must have the same name:

[HttpPost]
public void PostFile(IFormFile upload_file)
{
    _fileService.Add(upload_file);
}
Sign up to request clarification or add additional context in comments.

Comments

1

I will assume you meant byte[] by saying uint8 array. You can try using the new IFormFile interface.

[Route("api/File")]
public class FileController : Controller
{      
    // POST: api/file
    [HttpPost]
    public ActionResult Post(IFormFile file)
    {
     var uploadPath = Path.Combine(_hostingEnvironment.WebRootPath, "uploads");
     if (file.Length > 0) {
            var filePath = Path.Combine(uploads, file.FileName);
            using (var fileStream = new FileStream(filePath, FileMode.Create)) {
            //You can do anything with the stream e.g convert it to byte[]
            byte[] fileBytes = new byte[fileStream.Length];
            //Read the stream and write bytes to fileBytes 
            fileStream.Read(fileBytes, 0, fileBytes.Length);
            //fileBytes will contain the file byte[] at this point
            //Persist the file to disk
            await file.CopyToAsync(fileStream);
            }
        }
       //....
    }

Edit: Make sure the parameter name IFormFile file* matches the name you are sending from the client, in your case it should be IFormFile upload_file

2 Comments

Using the IFormFile and removing the [Produces("application/json")] (which I agree should be removed), ends up giving me file = null when debugging the application, which is the main problem I've had trying to get the file.
Any other suggestions?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.