Ng2-file-upload No access-control-allow-origin Header Is Present on the Requested Resource. Origin

Being able to upload files and use them afterward is the required characteristic of many applications. Sometimes this is not a piddling task to attain.

So, this is going to exist the topic for this blog post.

Nosotros are going to upload files to the server (.NET Core Web API role) and then use those files in our Angular client app. Also, in our next article, we are going to show how to download files using ASP.Cyberspace Core WebAPI and Angular and with it, we are going to complete this story.

In this postal service, we will stick to the images, only the logic is reusable for other file types as well.

  • ASP.NET Core Authentication with JWT and Angular
  • .Net Core Tutorial
  • ASP.NET Core Web API with EF Cadre Code-First Approach
  • Enabling CORS in ASP.Cyberspace Core Web API
  • Angular Cloth Tutorial

VIDEO: Uploading Files with ASP.NET Core WEB API and Angular video.


We have created the starter project to piece of work with through this blog post and it tin be downloaded from Upload Files .Internet Core Angular Starter Project. We strongly recommend downloading this project because it would exist much easier for you to follow along. In this project, we'll create a new user and display all the created users as an additional feature. Nosotros are going to modify the create-logic part by adding an upload functionality having a new user created together with an image path related to it.

We are going to split this commodity into the following sections:

  • Controller and Action Logic – .Cyberspace Core Part
  • Upload Files – Athwart Function
  • Using Uploaded File in Our Application
  • Uploading Multiple Files

Controller and Activeness Logic – .Cyberspace Core Function

After you've downloaded our starter project, you can commencement by opening the UploadFilesServer projection.

This project is created on summit of the SQL database, so to create that database, nosotros need to run the update-database command in a Package Director Console window. By doing this, our migrations will exist executed and the database with the required table volition be created.

The next step is to create a new folder Resource and inside it a new folder Images:

static files - how to upload files with .Net core

To keep, let's create a unproblematic API Controller file in the Controllers folder and proper name it UploadController.

Let'due south modify that file by calculation a new activity that will exist responsible for the upload logic:

[HttpPost, DisableRequestSizeLimit] public IActionResult Upload() {     try     {         var file = Request.Form.Files[0];         var folderName = Path.Combine("Resources", "Images");         var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName);          if (file.Length > 0)         {             var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');             var fullPath = Path.Combine(pathToSave, fileName);             var dbPath = Path.Combine(folderName, fileName);              using (var stream = new FileStream(fullPath, FileMode.Create))             {                 file.CopyTo(stream);             }              render Ok(new { dbPath });         }         else         {             return BadRequest();         }     }     take hold of (Exception ex)     {         return StatusCode(500, $"Internal server error: {ex}");     } }          

We are using a POST activity for the upload-related logic and disabling the asking size limit as well.

The logic within this action is pretty straightforward. Nosotros extract the file from the request and provide the path where the file volition be stored. Moreover, if the file has a length greater than zero, we just take its name and provide a total path on the server to store our file and a path to the database. This database path is going to exist returned as a result of this action after we place our stream into the divers binder. Nosotros could likewise bank check if a file with the same name already exists, merely didn't want to make the code more complicated at this moment.

To avoid the MultiPartBodyLength error, we are going to modify our configuration in the Startup.cs grade:

services.Configure<FormOptions>(o => {     o.ValueLengthLimit = int.MaxValue;     o.MultipartBodyLengthLimit = int.MaxValue;     o.MemoryBufferThreshold = int.MaxValue; });

Improve Reding from a Form Body

In our previous example, we use the Request.Course to read a form torso and for smaller applications, this is only fine. But hither, we are using a synchronous way to read the content from the class body, which in larger applications with so many users can lead to thread puddle starvation. To prevent that, we tin use asynchronous reading with the Asking.ReadFormAsync() expression.

All nosotros take to do is to modify the action signature and to modify our code inside just a flake:

[HttpPost, DisableRequestSizeLimit] public async Task<IActionResult> Upload() {     try     {         var formCollection = look Request.ReadFormAsync();         var file = formCollection.Files.Showtime();              //everything else is the same

This way, we read the form body in an asynchronous way and prevent the thread puddle starvation.

Serving Static Files

Usually, all the files in the wwwroot folder are servable for the client applications. We provide that past adding app.UseStaticFiles() in the Startup class in the Configure method. Of course, our uploaded images volition be stored in the Resources folder, and due to that, nosotros need to brand information technology servable every bit well. To exercise that, allow's change the Configure method in the Startup.cs form:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {     if (env.IsDevelopment())     {         app.UseDeveloperExceptionPage();     }      app.UseHttpsRedirection();      app.UseStaticFiles();     app.UseStaticFiles(new StaticFileOptions()     {         FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"StaticFiles")),         RequestPath = new PathString("/StaticFiles")     });      app.UseRouting();     app.UseCors("CorsPolicy");      app.UseAuthorization();      app.UseEndpoints(endpoints =>     {         endpoints.MapControllers();     }); }

And that'south all it takes. We have prepared our server-side app and information technology is time to leap right to the customer-side code.

If you want to learn in smashing detail about .Net Core project development, you can visit the .Cyberspace Cadre Tutorial.

Upload Files – Athwart Function

Let'south open the UploadFilesClient project and take a look at the app component files. For the sake of simplicity, we have implemented all of our logic within the app component.

To larn in great particular well-nigh Angular project development, you can read the Athwart Tutorial.

And then, the first thing nosotros are going to practise is to create a new Upload component in which nosotros will handle all the upload-related logic:

ng thousand component upload --spec imitation

This volition create iii files in the upload folder, and we are going to modify the upload.component.ts file first:

import { Component, OnInit, Output, EventEmitter } from '@angular/core'; import { HttpEventType, HttpClient } from '@angular/common/http';  @Component({   selector: 'app-upload',   templateUrl: './upload.component.html',   styleUrls: ['./upload.component.css'] }) consign class UploadComponent implements OnInit {   public progress: number;   public bulletin: string;   @Output() public onUploadFinished = new EventEmitter();    constructor(private http: HttpClient) { }    ngOnInit() {   }    public uploadFile = (files) => {     if (files.length === 0) {       return;     }      let fileToUpload = <File>files[0];     const formData = new FormData();     formData.append('file', fileToUpload, fileToUpload.proper name);      this.http.post('https://localhost:5001/api/upload', formData, {reportProgress: true, observe: 'events'})       .subscribe(event => {         if (consequence.type === HttpEventType.UploadProgress)           this.progress = Math.round(100 * outcome.loaded / event.total);         else if (event.type === HttpEventType.Response) {           this.message = 'Upload success.';           this.onUploadFinished.emit(upshot.body);         }       });   } }          

And then, what'south going on here?

We create two public variables. The first 1 to hold the bulletin when upload action is finished and the 2nd one to show the upload progress. In the uploadFile function, we create a formData object and append our file that we want to upload.

The next action is to send a post request and pay attending to it. Besides the URL and body backdrop, we have another JSON object which states that we want to track changes of our HTTP request progress. As long as the upload is in progress, we will update the progress variable and show that percentage on the screen, but as soon equally the upload is finished, we are going to write a message on the screen and emit a new upshot.

This event contains the body of our response, which is just the database path of our uploaded file. Nosotros demand that path to display the uploaded paradigm with other user details.

The files with the small size will be instantly uploaded and then, nosotros will see 100% progress equally presently equally we select our file. Simply for the larger files, the progress bar volition update its values for certain.

Displaying Functionalities

To display all of the mentioned functionalities on the screen, we need to change the upload.component.html file now:

<div form="row" style="margin-bottom:15px;">   <div class="col-dr.-3">     <input type="file" #file placeholder="Choose file" (modify)="uploadFile(file.files)" way="display:none;">     <button type="button" grade="btn btn-success" (click)="file.click()">Upload File</button>   </div>   <div course="col-dr.-4">     <span class="upload" *ngIf="progress > 0">       {{progress}}%     </span>     <span class="upload" *ngIf="message">       {{message}}     </span>   </div> </div>          

This logic is pretty straightforward except to the part where we hide the actual upload control and use its reference (#file) to invoke its click event with the push button, which looks much better. We could have styled the upload control equally well, but this is the better fashion, at least from our signal of view.

Finally, let's alter the upload.component.css file:

.upload{     font-weight:bold;     color:#28a745;     margin-left: 15px;     line-height: 36px; }          

And add a selector from the upload component to the app.component.html file:

<app-upload></app-upload> <div class="row">   <div grade="commencement-md-five col-md-2">     <push type="push" form="btn btn-principal" (click)="onCreate()">Create </button>   </div> </div>          

Excellent. We tin now inspect our issue:

create user - How to upload files with .Net Core

We tin check our Resources/Images folder too, to exist sure that the files are actually uploaded:

file uploaded - How to upload files in .NET Core

Using Uploaded File in Our Application

As soon as we press the Create push on our form, nosotros are going to encounter our newly created user. But its profile flick won't be rendered. So, let's fix that.

First, we need to react to the onUploadFinished event from the update component, and to exercise that let's modify the app.component.html file:

<app-upload (onUploadFinished)="uploadFinished($event)"></app-upload>

This change forces u.s.a. to modify the app.component.ts file too.

First, let's add together an additional property in that file:

public response: {dbPath: ''};

Then let'due south add the uploadFinished office to populate this property:

public uploadFinished = (event) => {     this.response = event;   }          

With this modification, we accept the response object in which nosotros tin can notice a path to exist saved in the database.

Lastly, we have to alter the user object in the onCreate function in the same file:

this.user = {   proper noun: this.name,   accost: this.accost,   imgPath: this.response.dbPath }          

Great job. At present we know the image file path related to the created user, and so let's use that knowledge to render that picture next to other user details.

To practice that, allow's modify a table within the app.component.html file:

<tabular array form="tabular array table-striped">   <thead>     <tr>       <th telescopic="col">Image</th>       <thursday scope="col">Proper noun</th>       <th telescopic="col">Accost</thursday>     </tr>   </thead>   <tbody>     <tr *ngFor="let user of users">       <td><img [src]="createImgPath(user.imgPath)" alt="profile picture" style="width:60px; peak:60px;"></td>       <td>{{user.proper name}}</td>       <td>{{user.address}}</td>     </tr>   </tbody> </table>          

And let's modify the app.component.ts file by adding the createImgPath part:

public createImgPath = (serverPath: string) => {   return `https://localhost:5001/${serverPath}`; }          

Our upshot should exist as follows:

used downloaded picture

Before we move to the multiple files upload functionality, just a reminder that if yous want to learn how to upload files using ASP.Internet Cadre Web API and Blazor WebAssembly, yous can read the BlazorWebassembly File Upload article from the Blazor WASM series.

Uploading Multiple Files

If nosotros desire to upload multiple files in any of our projects, nosotros need to modify both the server and client-side code.

So let's kickoff with the server-side:

public IActionResult Upload() {     try     {         var files = Request.Grade.Files;         var folderName = Path.Combine("StaticFiles", "Images");         var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName);          if (files.Whatever(f => f.Length == 0))         {             return BadRequest();         }          foreach (var file in files)         {             var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');             var fullPath = Path.Combine(pathToSave, fileName);             var dbPath = Path.Combine(folderName, fileName); //you lot can add this path to a list and and so return all dbPaths to the client if crave              using (var stream = new FileStream(fullPath, FileMode.Create))             {                 file.CopyTo(stream);             }         }          return Ok("All the files are successfully uploaded.");     }     catch (Exception ex)     {         return StatusCode(500, "Internal server fault");     } }

Afterward this modification, let'due south alter the customer-side. First, we need to change the input type file command by adding the multiple attribute:

<input type="file" #file placeholder="Choose file" (alter)="uploadFile(file.files)" style="display:none;" multiple>

Later on that, we are going to modify the uploadFile function:

public uploadFile = (files) => {   if (files.length === 0) {     return;   }    permit filesToUpload : File[] = files;   const formData = new FormData();        Array.from(filesToUpload).map((file, index) => {     return formData.append('file'+index, file, file.proper noun);   });    this.http.post('https://localhost:5001/api/upload', formData, {reportProgress: true, observe: 'events'})     .subscribe(event => {       if (event.type === HttpEventType.UploadProgress)         this.progress = Math.round(100 * event.loaded / event.full);       else if (outcome.type === HttpEventType.Response) {         this.bulletin = 'Upload success.';         this.onUploadFinished.emit(event.body);       }     }); }

I interesting affair to pay attending to is the apply of the Array.from() function. Even though the filesvariable contains all the selected files, it is not an array. So, in order to use the mapfunction, we are using the Array.from()syntax, which will convert the array-like object into the new array copy.  The rest of the logic is pretty straight forward.

And that is all that takes. At present you lot can examination your code and bank check that your files are uploaded.

Conclusion

In this article, we take learned:

  • How to code our server-side activeness to handle file uploading
  • The mode to create an upload component in our Athwart application
  • How to use uploaded files in the Angular awarding

In the next article, you can read how to Download Files with ASP.Internet Core Web API and Angular.

geigerwency1943.blogspot.com

Source: https://code-maze.com/upload-files-dot-net-core-angular/

0 Response to "Ng2-file-upload No access-control-allow-origin Header Is Present on the Requested Resource. Origin"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel