【问题标题】:Passing CSV file from Angular7 to MVC .Net Core将 CSV 文件从 Angular7 传递到 MVC .Net Core
【发布时间】:2019-02-20 23:37:36
【问题描述】:

我正在尝试将 CSV 文件传递​​到我的后端,以利用库来解析 CSV 数据。

我有一个 Angular7 前端和一个 C# .Net Core MVC 后端,它利用打字稿中的 HttpClient 来往后端传递数据和对象。

我尝试了许多解决方案,但收效甚微(最接近的是我可以在代码中访问控制器,但文件永远不会被传入)。

我试图避免对 CSV 进行任何类型的序列化或转换,直到它到达控制器,所以我想找到一个可以将整个 CSV 发送到后端的解决方案。

任何帮助将不胜感激。

service.ts

// Parse CSV
// The CSV always reaches this part of the code and I can inspect it.
parseCsv$(file: File): Observable<Dto> {
    const request$ = this.http.post<Dto>(
        location.origin + '/api/csvimport',
        file,
        { headers: new HttpHeaders({ 'Content-Type': 'multipart/form-data' }) }
    ).pipe(
        map((response: <Dto>) => response)
    );

    request$.subscribe();

    return request$;
}

CsvImportController.cs

    [HttpPost]
    [ProducesResponseType(typeof(Dto), 200)]

    // The 'file' variable below is always null
    public async Task<IActionResult> ParseCsv([FromBody]IFormFile file)
    {
        // do work here

【问题讨论】:

    标签: c# csv asp.net-core file-upload angular7


    【解决方案1】:

    您不应在文件上传中使用 FromBody 参数。

    您应该使用 request.Form.Files collection 来获取上传的文件, 或者

    您可以在控制器动作中使用 IList,如下所示。

    以下 API 获取文件列表,然后将其保存在服务器上的临时文件夹中。

    [HttpPost("UploadFiles")]
    public async Task<IActionResult> Post(List<IFormFile> files)
    {
        long size = files.Sum(f => f.Length);
    
        // full path to file in temp location
        var filePath = Path.GetTempFileName();
    
        foreach (var formFile in files)
        {
            if (formFile.Length > 0)
            {
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await formFile.CopyToAsync(stream);
                }
            }
        }
    
        // process uploaded files
        // Don't rely on or trust the FileName property without validation.
    
        return Ok(new { count = files.Count, size, filePath});
    }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      所以我能够解决这个问题,

      我需要将File 更改为FileList,然后使用FormData 附加文件。我还需要删除我的内容标题,因为让后端处理键入内容本身会阻止错误被抛出。在我的控制器中,我必须使用 IEnumerable&lt;IFormFile&gt; 才能完全正常工作。

      我不完全明白为什么我必须使用FileList 上传一个文件,但这是发送文件所必需的 文件。如果我发现更多,我会更新我的答案。

      编辑:解决上述问题,在 MDN 文档中,它指出 “所有 &lt;input&gt; 元素节点都有一个 FileList 类型的文件属性,它允许访问此列表中的项目” (https://developer.mozilla.org/en-US/docs/Web/API/FileList) 因此,为了访问一个文件,您实际上需要访问 FileList 数组的第一个索引 (FileList[0])。我可能对此有误解,请随时发表评论。

      service.ts

      parseCsv$(files: FileList): Observable<Dto> {
          const formData = new FormData();
          Array.from(files).forEach(
              (file: File) => formData.append(file.name, file)
          );
      
          return this.http.post<Dto>(
              location.origin + '/api/csvimport',
              formData)
          .pipe(
              map((response: <Dto>) => response)
          );
      }
      

      CsvImportController.cs

      [HttpPost]
      [ProducesResponseType(typeof(Dto), 200)]
      public async Task<IActionResult> ParseCsv(IEnumerable<IFormFile> files)
      {
          // Work here...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-27
        • 2019-02-11
        • 1970-01-01
        • 2020-10-17
        • 1970-01-01
        • 2018-11-08
        相关资源
        最近更新 更多