【问题标题】:File upload with ASP.Net Core 2.0 Web API and React.js使用 ASP.Net Core 2.0 Web API 和 React.js 上传文件
【发布时间】:2017-09-24 15:29:43
【问题描述】:

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

.Net 核心 (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");
        }
    }

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

【问题讨论】:

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


    【解决方案1】:

    我的工作如下:

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

    并在react中编写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");
        }
    }
    

    完美运行。谢谢!

    【讨论】:

    • 我们可以像这样使用 REST api
    【解决方案2】:

    这个答案是正确的,但我在我的 API 中保存图像时遇到问题,所以我改变了你看到的方法,然后工作得很好。您应该在 API 方法中将参数设置为 [FromForm]

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

    【讨论】:

    • 这肯定是不正确的,你不能有一个包含空格的属性名称......
    • @Luke 我相信他的意思是说[FromForm] - 这只是一个错字
    【解决方案3】:
    [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 };
            }
        }
    

    在 UI 中使用这个

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

    【讨论】:

      【解决方案4】:

      在我的情况下,我只是错过了在我的表单中添加 multipart/form-data

      如果您的控制器正在接受使用 IFormFile 上传的文件,但您发现该值始终为 null,请确认您的 HTML 表单指定了 enctype多部分/表单数据。如果未在 元素上设置此属性,则不会发生文件上传,并且任何绑定的 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 属性以仅允许上传单个文件。

      【讨论】:

        猜你喜欢
        • 2020-08-25
        • 2016-11-14
        • 2018-07-05
        • 2017-05-13
        • 2021-07-07
        • 1970-01-01
        • 2017-10-21
        • 2017-11-01
        • 2021-08-09
        相关资源
        最近更新 更多