Having some issues trying to pass FormData from an Angular 12 app to a .Net Core API. Every attempt to send the data gets denied in preflight and never actually calls the backend endpoint (confirmed with Console.WriteLine there).
Followed the same patterns in many videos and websites and even created a side projected where it was able to work but for some reason in the main app it never sends. Only difference is that our main app uses PrimeNG as a framework so that is the main driver of collecting the files from the users. I've read their documentation but still not having success with it. Hopefully someone out there can help.
Attachment-Form Component
File Upload <span >(Max File Size: 10MB)</span>
<p-fileUpload
#form
name="fileUpload[]"
multiple="multiple"
accept="{{ acceptedFiles }}"
maxFileSize="10000000"
customUpload="true"
(uploadHandler)="uploadFiles($event)"
>
<ng-template pTemplate="content">
<div
*ngIf="form.files.length === 0 && uploadedFiles.length === 0"
>
<i ></i>DRAG & DROP FILES OR CLICK CHOOSE | THEN
PRESS UPLOAD
</div>
<div *ngIf="uploadedFiles.length !== 0">
<div *ngFor="let file of uploadedFiles; let i">
<div >
{{ file.name }} - {{ file.size }} bytes
</div>
<div>
<button
type="button"
icon="pi pi-trash"
pbutton
(click)="showFile(file)"
>
<span aria-hidden="true"></span
><span aria-hidden="true" > </span>
</button>
</div>
</div>
</div>
</ng-template>
</p-fileUpload>
</div>
<div>
File Upload <span >(Max File Size: 10MB)</span>
<p-fileUpload
#form
name="fileUpload[]"
multiple="multiple"
accept="{{ acceptedFiles }}"
maxFileSize="10000000"
customUpload="true"
(uploadHandler)="uploadFiles($event)"
>
<ng-template pTemplate="content">
<div
*ngIf="form.files.length === 0 && uploadedFiles.length === 0"
>
<i ></i>DRAG & DROP FILES OR CLICK CHOOSE | THEN
PRESS UPLOAD
</div>
<div *ngIf="uploadedFiles.length !== 0">
<div *ngFor="let file of uploadedFiles; let i">
<div >
{{ file.name }} - {{ file.size }} bytes
</div>
<div>
<button
type="button"
icon="pi pi-trash"
pbutton
(click)="showFile(file)"
>
<span aria-hidden="true"></span
><span aria-hidden="true" > </span>
</button>
</div>
</div>
</div>
</ng-template>
</p-fileUpload>
</div>
Form Component (for custom upload event)
uploadFiles(event) {
let files: any = <File>event.files;
// console.log(files);
const fileData = new FormData();
for (let i = 0; i < files.length; i ) {
fileData.append('file', files[i], files[i].name);
// Console Log for my sake
fileData.forEach((item) => console.log('fileData', item));
}
this.attachmentsService.uploadFiles(fileData).subscribe(
(res) => console.log(res),
(err) => console.log(err)
);
}
Attachment Service
uploadFiles(upload: any) {
//Confirmation they are still there
upload.forEach((item) => console.log('in api call', item));
return this.http.post(
'apiendpoint',
upload
);
}
//I've used these headers and additional content-type headers as well and nothing worked
headers = new HttpHeaders()
.set('content-type', 'application/json')
.set('Access-Control-Allow-Origin', '*')
.set('Access-Control-Allow-Methods', '*');
Any ideas are apricated. Thanks,
CodePudding user response:
The problem is not related to FormData nor PrimeNG. You are having trouble with CORS. It is likely that it worked before because you had the Angular App and the Web API on the same domain and port and it is equally likely that now it is not working because they are no longer on the same domain or port.
The better solution, in the long term, is to enable CORS on the server side. Since you mentioned that you are using ASP.NET Core, you should follow their documentation as it is quite good.
Also, if you don't know what CORS (Cross-Origin Resource Sharing) is, there is a great article on the MDN website explaining everything.
Essential, your browser is denying your request because it does not comply with a security feature that browsers have which is called SOP (Same-Origin Policy). CORS is a mechanism to loosen up constraints applied by SOP.
If you need further help, add the version of the .NET Core that you are using and the content of your Startup.cs file to your question.
CodePudding user response:
This is not a problem with your Angular code. The problem is that your server is not configured to allow cross origin requests (CORS). You dev server is on port 5000 and your Angular dev server is on port 4200, making the request from a different origin.
Here's the documentation on how to enable CORs in dotnet.
This stackoverflow post also has some good information.
The way I've configured CORs in dotnet is in Startup.cs:
public class Startup {
public void ConfigureServices(IServiceCollection services){
//some configuration here
services.AddCors();
//likely some more configuration
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MyDbContext dataContext){
//some configuration
app.UseCors(
options => options
.AllowAnyHeader()
.WithMethods("OPTIONS", "GET", "POST", "PUT", "DELETE")
.AllowAnyOrigin()
);
//perhaps some more configuration
}
}
I'd recommend giving the dotnet core angular template a try. The project template will set up your app correctly and you do not have to mess with CORs.
