'How to upload files and send data from angular to webapi (.net)

I'm trying to pass data from angular 9 to a WebApi controller, basically I'm trying to send two lists, a list with files and another with some extra data. The issue is that I'm getting error 400 when passing the list of files to the controller.

angular model class:

export class UploadData 
{
public lstUploadFiles: any[];
public fileList: File[];
}

component:

ud = new UploadData();

upload() 
{
const filesData = new FormData();
this.fileList.foreach((f) => filesData.append('certificates', f));

this.ud.lstUploadFiles = this.lstUploadFiles;
this.ud.fileList = this.fileList;

//request
this.uploadFiles = this.service.uploadFiles(this.ud)
 ................
....................
}

uploadFiles(files: any): Observable<ApiResponse> {
console.log(files); // here all is ok, object full with data
return this.http.post<ApiResponse>(this.apiUrl +  "Upload/", {files}, {withCredentials: true})
.pipe(map(model =>{
return model;
}),
catchError(error => {
this.handleError(error);
return throwError(error);
})));
}

dotnet:

model:

public class FileUploadDTO
{
public List<IFormFile> fileList {get; set:}
public List<ReportDTO> lstUploadFiles{get; set;}

}

controller:

[HttpPost]
[Route("Upload")]
public ReportResposeDTO UploadFiles([FromBody] FileUploadDTO input) 
{
//here input.fileList is always null as well input.lstUploadFiles
}

Note that I'm using file type IFormFile on dotnet model:

public List<IFormFile> fileList {get; set:}

And from angular I'm sending the object this.ud

this.ud.fileList = this.fileList;

and fileList is:

const filesData = new FormData();
    this.fileList.foreach((f) => filesData.append('certificates', f));

It seems that there is a problem with filetypes, because when I change the type in controller from IFormFile to anything else the list is coming null, but if I leave it as IFormFile then I get 400 error ... any idea?



Solution 1:[1]

I have an older project with .NET Framework 4.6.1. Maybe there have been some changes in .NET Core.

I upload a file like this:

let observable = this.httpClient.post<IHttpPostImageUploadResult>(this.apiUrl + actionUrl, formData)

where formDatais of type FormData.

In the .NET controller action I have no parameter. Instead I read the data like this:

public async Task<IHttpActionResult> UploadFile()
{
    var provider = new MultipartMemoryStreamProvider();
    byte[] file;
    MediaTypeHeaderValue contentType;
    string fileName;

    await Request.Content.ReadAsMultipartAsync(provider);

    var fileNameParam = provider.Contents[0].Headers.ContentDisposition.Parameters
                .FirstOrDefault(p => p.Name == "filename");
    fileName = fileNameParam?.Value.Trim('"') ?? "";
    contentType = provider.Contents[0].Headers.ContentType;
    file = await provider.Contents[0].ReadAsByteArrayAsync();

And to read further form data:

    var name = await provider.Contents[1].ReadAsStringAsync();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 noox