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

浪尽此生 提交于 2020-06-09 11:39:27

问题


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.


回答1:


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!




回答2:


[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);
  });
 }



回答3:


In my case i simply missed to add multipart/form-data in my form.

If your controller is accepting uploaded files using IFormFile but you find that the value is always null, confirm that your HTML form is specifying an enctype value of multipart/form-data. If this attribute isn't set on the element, the file upload won't occur and any bound IFormFile arguments will be null.

Example:-

<form method="post" enctype="multipart/form-data" asp-controller="UploadFiles" asp-action="Index">
        <div class="form-group">
            <div class="col-md-10">
                <p>Upload one or more files using this form:</p>
                <input type="file" name="files" multiple />
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-10">
                <input type="submit" value="Upload" />
            </div>
        </div>
    </form>

Remove the multiple attribute on this input element to allow just a single file to be uploaded.



来源:https://stackoverflow.com/questions/46391735/file-upload-with-asp-net-core-2-0-web-api-and-react-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!