使用ASP.Net Core 2.0 Web API和React.js上传文件

时间:2017-09-24 15:29:44

标签: reactjs file-upload asp.net-core-2.0

我是react.js和ASP.Net核心2.0的新手。现在使用ASP.Net core 2.0作为后端API和react.js作为应用程序接口(前端)编写项目。我想知道如何上传文件。我尝试了如下,但在后端方面,参数值(IFromFile文件)始终为null。而且似乎文件没有正确发布。这是我的代码:

.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");
        }
    }

请告知我该如何解决这个问题。

4 个答案:

答案 0 :(得分:6)

我完成了以下工作:

at .Net core 2.0 web api

使用Microsoft.AspNetCore.Http;

我创建了一个模型类

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

然后我创建了一个控制器类并编写了如下函数。

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

编写api调用函数如下:

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

它完美无缺。谢谢!

答案 1 :(得分:3)

这个答案是正确的,但是我在将图像保存到API中时遇到了问题,因此我按您所见的那样更改了方法,然后运行良好。您应该在API方法中将参数设置为[FromForm]

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

答案 2 :(得分:1)

就我而言,我只是错过了在表单中添加 multipart / form-data

如果您的控制器正在使用 IFormFile 接受上载的文件,但您发现该值始终为空,请确认您的HTML表单指定的 enctype 值为 multipart / form-data 。如果未在 元素上设置此属性,则不会进行文件上载,并且任何绑定的 IFormFile 参数将为空。

示例:-

<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>

删除此输入元素上的 multiple 属性,以仅允许上传单个文件。

答案 3 :(得分:0)

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

并在用户界面中使用此

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