【问题标题】:Accept a POSTED file [duplicate]接受 POSTED 文件 [重复]
【发布时间】:2019-12-29 03:09:50
【问题描述】:

我正在尝试使用 Angular 8 上传 PDF。我成功获取了用户在前端选择的文件。我正在将一些东西传递给后端,但是当我尝试从内存流中读取文件时,在我将其转换为字符串的测试期间,我得到“[object FileList]”而不是文件的内容。

这是我不熟悉的招摇的东西吗?我想我可能比以前更容易被卡住。

下面是我选择文件的 HTML。

    <div>
        <form [formGroup] = "uploadForm" (ngSubmit)="onSubmit()">      
      <div>
        <!-- TODO: rename profile -->
        <input type="file" name="profile" (change)="onFileSelect($event)" 
    accept=".pdf"/>
      </div>
      <div>
        <button type="submit">Upload</button>
      </div>
    </form>
  </div>

下面是我的打字稿:

    import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule} from '@angular/forms';

@Component({
  selector: 'app-pdf',
  templateUrl: './pdf.component.html',
  styleUrls: ['./pdf.component.css']
})
export class PDFComponent implements OnInit {

  SERVER_URL = "http://localhost:64528/api/uploadPDF";
  uploadForm: FormGroup; 
  file;

  constructor(private formBuilder: FormBuilder, private httpClient: HttpClient) { }

  ngOnInit() {
    this.uploadForm = this.formBuilder.group({
      profile:['']
    });
  }

  onFileSelect(event){
    var file = event.target.files;
    if(file.length > 0){
       this.file = event.target.files[0];
      this.uploadForm.get('profile').setValue(file);

      var confirm = this.uploadForm.get('profile').value;
    }
  }

  onSubmit(){
    const formData = new FormData();
    formData.append('file', this.uploadForm.get('profile').value);

    this.httpClient.post<any>(this.SERVER_URL, formData).subscribe(
      (res) => console.log(res),
      (err) => console.log(err)
    );
  }

}

下面是我的 C#

using HeadcountTrackingAPI.Repositories;
using HeadcountTrackingAPI.Utilities;
using Swashbuckle.Swagger.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;

namespace HeadcountTrackingAPI.Controllers
{
    public class PDFController : ApiController
    {
        // GET api/<controller>
        [SwaggerOperation("uploadPDF")]
        [HttpPost]
        [Route("api/uploadPDF")]
        public async Task<IHttpActionResult> UploadFile()
        {
            try
            {
                if (!Request.Content.IsMimeMultipartContent("form-data"))
                    throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

                // Initialize the memorty stream provider
                MultipartMemoryStreamProvider memoryStream = new MultipartMemoryStreamProvider();

                // Assign it's contents
                memoryStream = await Request.Content.ReadAsMultipartAsync();

                // Read the contents asynchronosly 
                using (System.IO.Stream pdfStream = await memoryStream.Contents.First().ReadAsStreamAsync())
                {

                    byte[] bytes = new byte[pdfStream.Length];

                    // streamBytes to the byte array starting a position 0 and ending at the end of the file
                    pdfStream.Read(bytes, 0, (int)pdfStream.Length);

                    var byteString = BitConverter.ToString(bytes);
                    string utfString = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
                }

                    return Ok(new { Posted = true });
            }
            catch (Exception ex)
            {
                ex.LogException();
                return InternalServerError(ex);
            }
        }
    }
}

以下是我访问过的资源 https://docs.microsoft.com/en-us/previous-versions/aspnet/dn202095(v%3Dvs.118)

'multipart/form-data' is not supported for this resource

https://www.c-sharpcorner.com/UploadFile/2b481f/uploading-a-file-in-Asp-Net-web-api/

Send a file via HTTP POST with C#

How To Accept a File POST

感谢所有帮助,谢谢。

【问题讨论】:

  • 如果您谈论的是 question 的第一条评论,他们谈论的是 question 中的代码,而不是answer,您应该在其中寻找答案 :)。
  • 是的,对不起,我很笨,我现在正在测试。 `string file1 = provider.BodyPartFileNames.First().Value;`这行给了我红色的sugglies,无法修复。
  • @AdamSchneider 如果您将鼠标悬停在这条线上,智能感知会提供任何建议吗?
  • 字符串 file1 = provider.FileData.First().LocalFileName;这应该是这样做的方法,但是 1. 我看到它访问我的文件系统并创建路径,但我没有看到它正在摄取文件,我在哪里看不到文件实际上将它发送到服务器,当我检查了响应消息我没有看到消息文件已上传。 2. 当我查看代码时,除非我遗漏了一些东西,否则我实际上并没有看到它保存代码的位置。
  • @AdamSchneider 您必须对其进行测试,但我认为在控制器中您可以使用类似 var file = Request.Files[0]; 的东西(或 Request.Files.FirstOrDefault() 不同之处在于 FirstOrDefault() 不会抛出如果请求中没有文件,则为空引用异常)。并从那里工作。 HttpPostedFileBase 作为控制器的参数也可能起作用。

标签: c# asp.net-web-api2 swagger angular-cli angular8


【解决方案1】:

试试这个:

[HttpPost]
[Route("api/uploadPDF")]
public async Task<IHttpActionResult> UploadFile()
{
    try
    {
        if (!Request.Content.IsMimeMultipartContent("form-data"))
        {
            return StatusCode(HttpStatusCode.UnsupportedMediaType);
        }

        var fileProvider = await Request.Content.ReadAsMultipartAsync();

        var pdfStream = await fileProvider.Contents.First().ReadAsStreamAsync();

        //do something with the pdf stream

        return Ok(new { Posted = true });                
    }
    catch (Exception ex)
    {
        ex.LogException();
        return InternalServerError(ex);
    }
}

【讨论】:

  • 值得注意的是,var pdfStream 可能包含一个using 语句以确保它被释放(iirc、内存流/文件流等对清理自己并不好)。
  • 我不断收到 ExceptionMessage:“提供的 'HttpContent' 实例无效。它没有带有 'boundary' 参数的 'multipart' 内容类型标头。↵参数名称:内容”。我在角度方面改变了我的内容类型,并尝试注释掉你的 if 语句,看看是否能让我通过它。我不知道为什么会发生这种情况,之前发生这种情况是因为我的旧函数需要内容类型“application/x-www-form-urlencoded”,但将其改回 Multipart/form-data 似乎并没有修复它.
  • 500 内部服务错误。 IDK,我觉得您的解决方案可能是正确的,但我无处可去
  • 那很痛,这是因为我定义了内容类型而不是边界,如果我只是不定义内容类型 Swagger 会自动正确地执行它。天哪。
猜你喜欢
  • 2017-09-12
  • 2016-05-27
  • 2017-10-12
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多