When looking at other answers and some google, everything seems to be fine, yet my controller never receives any data.
Api uris and such are correct, the request arrives at the correct controller
Angular snippet:
component.html - my input field
<div class="input-group">
<input type="file" #fileInput id="fileInput" (change)="stageFile()"
accept="csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">
<div class="input-group-append">
<button class="btn btn-primary" type="button" (click)="fileUpload()" [disabled]="!staged || uploading">
<span *ngIf="!uploading,else loadAnim">Upload</span>
<ng-template #loadAnim>Uploading...</ng-template>
</button>
</div>
</div>
component.ts - get data from view
@ViewChild('fileInput') fileInput;
private file: File;
public uploading = false;
public staged = false;
constructor(private uploadService: UploadService) { }
public stageFile(): void {
this.staged = true;
this.file = this.fileInput.nativeElement.files[0];
console.log(this.file)
}
public fileUpload():void {
this.uploading = true;
if (this.file != null)
this.uploadService.upload(this.file).subscribe();
this.staged = false;
this.uploading = false;
}
services.ts - handle actual ajax call
private uploadURI = environment.dataServiceURI + '/upload';
constructor(private http: HttpClient) {}
public upload(file: File): Observable<object> {
// create multipart form for file
let formData: FormData = new FormData();
formData.append('file', file, file.name);
const headers = new HttpHeaders().append('Content-Type', 'mulipart/form-data');
// POST
return this.http
.post(this.uploadURI, formData, {headers: headers})
.pipe(map(response => response));
}
.net core snippet
It is here where IFormFile file always contains null and thus my result is always 500
[HttpPost("upload")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public IActionResult ParseData([FromForm(Name = "file")] IFormFile file)
{
if (file == null)
return StatusCode(500);
(...)
return Ok()
}
Request Payload Info
From browser networking
------WebKitFormBoundarycBigaNKzS4qNcTBg
Content-Disposition: form-data; name="file"; filename="test_data_schema.xlsx"
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
------WebKitFormBoundarycBigaNKzS4qNcTBg--
Problem solved:
in service.ts it should be
const headers = new HttpHeaders().append('Content-Disposition', 'multipart/form-data');
instead of
const headers = new HttpHeaders().append('Content-Type', 'multipart/form-data');
Also in the .net controller, adding or removing [FromForm(Name = "file")] as parameter prefix does not change the behavior. It works perfectly fine with or without it. As hugo pointed out in the comments it's convention based as long as the param name matches to name in the form data.
Agree, the Content-Disposition header did help. One more condition should be met: the first parameter of formData.append(....) method: the first parameter of
formData.append(...)
method:
should be the same with the name of agrument in controller action:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With