File upload with ASP.Net Core 2.0 Web API and React.js

I have done the job as follow:

at .Net core 2.0 web api

using Microsoft.AspNetCore.Http;

I created a model class

namespace Marter_MRM.Models
{
    public class FileUploadViewModel
    {
        public IFormFile File { get; set; }
        public string source { get; set; }
        public long Size { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
        public string Extension { get; set; }
    }
}

And then I created a controller class and wrote the function as follow.

[HttpPost]
[Route("upload")]
public async Task<IActionResult> Upload(FileUploadViewModel model) {
      var file = model.File;

      if (file.Length > 0) {
           string path = Path.Combine(_env.WebRootPath, "uploadFiles");
           using (var fs = new FileStream(Path.Combine(path, file.FileName), FileMode.Create))
           {
                await file.CopyToAsync(fs);
           }

           model.source = $"/uploadFiles{file.FileName}";
           model.Extension = Path.GetExtension(file.FileName).Substring(1);
      }
    return BadRequest();
}

And write api call function in react as follow:

handleUploadClick(event){
    event.preventDefault();
    var self = this;
    var apiBaseUrl =  axios.defaults.baseURL + "user/upload";
    if(this.state.filesToBeSent.length>0){
        var filesArray = this.state.filesToBeSent;
        let f = new FormData();
        for(var i in filesArray){
        //console.log("files",filesArray[i][0]);
             f = new FormData();
             f.append("File",filesArray[i][0] )
             axios.post(apiBaseUrl, f, {
                    headers: {'Content-Type': 'multipart/form-data'}
             });
        }
        alert("File upload completed");
    }
    else{
        alert("Please select files first");
    }
}

It works perfect. Thanks!


This answer is true but I have problem with saving an image in my API so I change the method as you see and then work nice. You should set the parameter as [FromForm] in your API method

public async Task<IActionResult> Upload([FromForm]FileUploadViewModel model){...}

[Route("api/[controller]")]
[ApiController]
public class UploaderController : ControllerBase
{
    [HttpPost]
    public dynamic UploadJustFile(IFormCollection form)
    {
        try
        {
            foreach (var file in form.Files)
            {
                string path = Path.Combine(@"C:\uploadFiles");
                using (var fs = new FileStream(Path.Combine(path, file.FileName), FileMode.Create))
                {
                    file.CopyToAsync(fs);
                }
                UploadFile(file);
            }

            return new { Success = true };
        }
        catch (Exception ex)
        {
            return new { Success = false, ex.Message };
        }
    }

and in UI use this

uploadJustFile(e) {
 e.preventDefault();
 let state = this.state;

this.setState({
  ...state,
  justFileServiceResponse: 'Please wait'
});

if (!state.hasOwnProperty('files')) {
  this.setState({
    ...state,
    justFileServiceResponse: 'First select a file!'
  });
  return;
}

let form = new FormData();

for (var index = 0; index < state.files.length; index++) {
  var element = state.files[index];
  form.append('file', element);
}
debugger;
axios.post('/api/uploader', form)
  .then((result) => {
    let message = "Success!"
    if (!result.data.success) {
      message = result.data.message;
    }
    this.setState({
      ...state,
      justFileServiceResponse: message
    });
  })
  .catch((ex) => {
    console.error(ex);
  });
 }