Angular Passing FormData to WebAPI. Getting null

2020-01-29 17:28发布

问题:

I am passing FormData object from Angular 7 to WebAPI but I getting a null

Any help is appreciated. Thanks

From typescript, i have

selectFile(event){ 
      if (event.target.files[0]) {
          this.blob = event.target.files[0];
      }
    }

save() {

let formDataDTO = new FormData();
        formDataDTO.append('file', this.blob, this.fileName);

this.http.post<T>(this.url, JSON.stringify(formDataDTO), this.getHeaders())
      .pipe(
      catchError(error => {

      }))

}

In WebAPI,

[HttpPost]
        [Route("file/add")]

        public HttpResponseMessage Save([FromBody] HttpPostedFileBase form)
        {
            var test = form; // form is always null
//cannot access Request.Content.file
// Request.Content.isFormData() is false
// Request.Content.IsMimeMultipartContent() cannot be evaluated

        }

回答1:

try this :

first of all, define a service to send the files :

@Injectable()
export class UploadFileSimpleService {

  private baseUrl = "api/SimpleUpload";

  constructor(private http: Http) {}

  private extractData(res: Response) {
    const body = res.json();
    return body || {};
  }

  private handleError(error: Response): Observable<any> {
    console.error("observable error: ", error);
    return Observable.throw(error.statusText);
  }

  postTicket(filesList: FileList): Observable<any> {
    if (!filesList || filesList.length === 0) {
      return Observable.throw("Please select a file.");
    }

    const formData: FormData = new FormData();

    for (let i = 0; i < filesList.length; i++) {
      formData.append(filesList[i].name, filesList[i]);
    }

    const headers = new Headers();
    headers.append("Accept", "application/json");
    const options = new RequestOptions({ headers: headers });

    return this.http
      .post(`${this.baseUrl}/SaveTicket`, formData, options)
      .map(this.extractData)
      .catch(this.handleError);
  }
}

then create a form to select the files :

<form #form="ngForm" (submit)="submitForm(form)" novalidate>

    <div class="form-group">
        <label class="control-label">Screenshot(s)</label>
        <input #screenshotInput required type="file" multiple (change)="fileChange($event)" class="form-control" name="screenshot">
    </div>

    <button class="btn btn-primary" [disabled]="form.invalid" type="submit">Ok</button>
</form>

here, call the UploadFileSimpleService to send the files after submitting the form :

   @ViewChild("screenshotInput") screenshotInput: ElementRef;

   constructor(private uploadService: UploadFileSimpleService  ) {}

   submitForm(form: NgForm) {
     const fileInput: HTMLInputElement = this.screenshotInput.nativeElement;
     console.log("fileInput.files", fileInput.files);

     this.uploadService
       .postTicket(fileInput.files)
       .subscribe(data => {
         console.log("success: ", data);
       });
   }

and finally in your MVC Controller :

    private readonly IHostingEnvironment _environment;
    public SimpleUploadController(IHostingEnvironment environment)
    {
        _environment = environment;
    }

    [HttpPost("[action]")]
    public async Task<IActionResult> SaveTicket()
    {
        //TODO: save the ticket ... get id
        var uploadsRootFolder = Path.Combine(_environment.WebRootPath, "uploads");
        if (!Directory.Exists(uploadsRootFolder))
        {
            Directory.CreateDirectory(uploadsRootFolder);
        }

        var files = Request.Form.Files;
        foreach (var file in files)
        {
            //TODO: do security checks ...!

            if (file == null || file.Length == 0)
            {
                continue;
            }

            var filePath = Path.Combine(uploadsRootFolder, file.FileName);
            using (var fileStream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(fileStream).ConfigureAwait(false);
            }
        }

        return Created("");
    }