Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm new to both react.js and ASP.Net core 2.0. And now writing a project using ASP.Net core 2.0 as back end API and react.js as application interface (front end). I'd like to know how to upload file. I have tried as follow but in the Back end side the parameter value (IFromFile file) is always null. And it seems that file was not posted correctly. Here are my codes:

.Net core (API)

[HttpPost]
        [Route("upload")]
        public async Task Upload(IFormFile file)
        {
            if (file == null) throw new Exception("File is null");
            if (file.Length == 0) throw new Exception("File is empty");

            using (Stream stream = file.OpenReadStream())
            {
                using (var binaryReader = new BinaryReader(stream))
                {
                    var fileContent =  binaryReader.ReadBytes((int)file.Length);
                   // await _uploadService.AddFile(fileContent, file.FileName, file.ContentType);
                }
            }
        }

React.js

handleClick(event){
        event.preventDefault();
        // console.log("handleClick",event);
        var self = this;
        var apiBaseUrl =  axios.defaults.baseURL + "user/upload";
        if(this.state.filesToBeSent.length>0){
            var filesArray = this.state.filesToBeSent;
            const reader = new FileReader();
            for(var i in filesArray){
                //console.log("files",filesArray[i][0]);
                var file = filesArray[i][0];
                axios.post(apiBaseUrl, {data: file});
            }
            alert("File upload completed");
        }
        else{
            alert("Please select files first");
        }
    }

Please advise how can I solve the issue.

like image 418
Ye Yint Avatar asked Sep 24 '17 15:09

Ye Yint


1 Answers

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!

like image 134
Ye Yint Avatar answered Oct 23 '22 09:10

Ye Yint