Being able to upload files and use them afterward is the required feature of many applications. Sometimes this is not a trivial task to accomplish.
So, this is going to be the topic for this blog post.
We are going to upload files to the server (.NET Core Web API part) 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.NET Core WebAPI and Angular and with it, we are going to complete this story.
In this post, we will stick to the images, but the logic is reusable for other file types as well.
VIDEO: Uploading Files with ASP.NET Core WEB API and Angular video.
We have created the starter project to work with through this blog post and it can be downloaded from Upload Files .NET Core Angular Starter Project. We strongly recommend downloading this project because it would be 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. We 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 them.
If you want to download our finished project, you can do that from Upload Files .NET Core Angular Finished Project.
Let’s start.
Controller and Action Logic – .NET Core Part
After we’ve downloaded our starter project, we can start by opening the UploadFilesServer
project.
This project is created on top of the SQL database, so to create that database, we need to run the update-database
command in a Package Manager Console window. By doing this, we will execute our migrations and create the database with the required table.
The next step is to create a newResources
folder and inside it a new folder Images
:
To continue, let’s create a simple API Controller file in the Controllers
folder and name it UploadController
.
Let’s modify that file by adding a new action that will be 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); } return Ok(new { dbPath }); } else { return BadRequest(); } } catch (Exception ex) { return StatusCode(500, $"Internal server error: {ex}"); }}
We use a POST action for the upload-related logic and disable the request size limit as well.
The logic inside this action is pretty straightforward. We extract the file from the request and provide the path to store the file. Moreover, if the file has a length greater than zero, we just take its name and provide a full path on the server to store our file and a path to the database. This database path is going to be returned as a result of this action after we place our stream into the defined folder. We could also check if a file with the same name already exists, but 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 Program.cs
class:
builder.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.Form
to read a form body and for smaller applications, this is just fine. But here, we are using a synchronous way to read the content from the form body, which in larger applications with so many users can lead to thread pool starvation. To prevent that, we can use asynchronous reading with the Request.ReadFormAsync()
expression.
All we have to do is to modify the action signature and modify our code inside just a bit:
[HttpPost,DisableRequestSizeLimit]public async Task<IActionResult> Upload(){ try { var formCollection = await Request.ReadFormAsync(); var file = formCollection.Files.First(); //everything else is the same
This way, we read the form body in an asynchronous way and prevent the thread pool starvation.
Serving Static Files
Usually, all the files in the wwwroot
folder are servable for the client applications. We provide that by adding app.UseStaticFiles()
in the Startup
class in the Configure
method. Of course, our uploaded images will be stored in the Resources
folder, and due to that, we need to make it servable as well. To do that, let’s modify the Program.cs
class:
app.UseHttpsRedirection();app.UseCors("CorsPolicy");app.UseStaticFiles();app.UseStaticFiles(new StaticFileOptions(){ FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Resources")), RequestPath = new PathString("/Resources")});
And that’s all it takes. We have prepared our server-side app and it is time to jump right to the client-side code.
If you want to learn in great detail about .NET Core project development, you can visit the .NET Core Tutorial.
Upload Files – Angular Part
Let’s 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 inside the app component.
To learn in great detail about Angular project development, you can read the Angular Tutorial.
So, the first thing we are going to do is to create a new Upload component in which we will handle all the upload-related logic:
ng g component upload --skip-tests
This will create three files in the upload
folder, and we are going to modify the upload.component.ts
file first:
import { HttpClient, HttpEventType, HttpErrorResponse } from '@angular/common/http';import { Component, EventEmitter, OnInit, Output } from '@angular/core';@Component({ selector: 'app-upload', templateUrl: './upload.component.html', styleUrls: ['./upload.component.css']})export class UploadComponent implements OnInit { progress: number; message: string; @Output() public onUploadFinished = new EventEmitter(); constructor(private http: HttpClient) { } ngOnInit() { } uploadFile = (files) => { if (files.length === 0) { return; } let fileToUpload = <File>files[0]; const formData = new FormData(); formData.append('file', fileToUpload, fileToUpload.name); this.http.post('https://localhost:5001/api/upload', formData, {reportProgress: true, observe: 'events'}) .subscribe({ next: (event) => { if (event.type === HttpEventType.UploadProgress) this.progress = Math.round(100 * event.loaded / event.total); else if (event.type === HttpEventType.Response) { this.message = 'Upload success.'; this.onUploadFinished.emit(event.body); } }, error: (err: HttpErrorResponse) => console.log(err) }); }}
So, what’s going on here?
We create two public properties. The first one is to hold the message when the upload action is finished and the second one is to show the upload progress. In the uploadFile
function, we create a formData
object and append the file that we want to upload.
The next action is to send a post request and pay attention to it. Besides the URL and body properties, 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 as the upload is finished, we are going to write a message on the screen and emit a new event.
This event contains the body of our response, which is simply the database path of our uploaded file. We need that path to display the uploaded image with other user details.
The files with the small size will be instantly uploaded so, we will see 100% progress as soon as we select our file. But for the larger files, the progress bar will update its values for sure.
Template File Modification
To display all of the mentioned functionalities on the screen, we need to modify the upload.component.html
file now:
<div class="row" style="margin-bottom:15px;"> <div class="col-md-3"> <input type="file" #file placeholder="Choose file" (change)="uploadFile(file.files)" style="display:none;"> <button type="button" class="btn btn-success" (click)="file.click()">Upload File</button> </div> <div class="col-md-4"> <span class="upload" *ngIf="progress > 0"> {{progress}}% </span> <span class="upload" *ngIf="message"> {{message}} </span> </div></div>
This logic is pretty straightforward except for the part where we hide the actual upload control and use its reference (#file
) to invoke its click event with the button, which looks much better. We could have styled the upload control as well, but this is the better way, at least from our point of view.
Finally, let’s modify 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 class="offset-md-5 col-md-2"> <button type="button" class="btn btn-primary" (click)="onCreate()">Create </button> </div></div>
Excellent. We can now inspect our result:
We can check our Resources/Images
folder as well, to be sure that the files are really uploaded:
Using Uploaded Files in Our Application
As soon as we press the Create
button on our form, we are going to see our newly created user. But its profile picture won’t be rendered. So, let’s fix that.
First, we need to react to the onUploadFinished
event from the update component, and to do that let’s modify the app.component.html
file:
<app-upload (onUploadFinished)="uploadFinished($event)"></app-upload>
This change forces us to modify the app.component.ts
file as well.
First, let’s add an additional property to that file:
response: {dbPath: ''};
Then let’s add the uploadFinished
function to populate this property:
uploadFinished = (event) => { this.response = event; }
With this modification, we have the response object in which we can find a path to be saved in the database.
Lastly, we have to modify the user object in the onCreate
function in the same file:
onCreate = () => { this.user = { name: this.name, address: this.address, imgPath: this.response.dbPath }
Now we know the image file path related to the created user, so let’s use that knowledge to render that picture next to other user details.
To do that, let’s change the table inside the app.component.html
file:
<table class="table table-striped"> <thead> <tr> <th scope="col">Image</th> <th scope="col">Name</th> <th scope="col">Address</th> </tr> </thead> <tbody> <tr *ngFor="let user of users"> <td><img [src]="createImgPath(user.imgPath)" alt="profile picture" style="width:60px; height:60px;"></td> <td>{{user.name}}</td> <td>{{user.address}}</td> </tr> </tbody></table>
And let’s modify the app.component.ts
file by adding the createImgPath
function:
public createImgPath = (serverPath: string) => { return `https://localhost:5001/${serverPath}`; }
Now, once we upload the file and create a user, we can see all the info in the table:
Before we move to the multiple files upload functionality, just a reminder that if you want to learn how to upload files using ASP.NET Core Web API and Blazor WebAssembly, you can read the BlazorWebassembly File Upload article from the Blazor WASM series.
Uploading Multiple Files
If we want to upload multiple files in any of our projects, we need to modify both the server and client-side code.
So let’s start with the server-side:
public IActionResult Upload(){ try { var files = Request.Form.Files; var folderName = Path.Combine("StaticFiles", "Images"); var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName); if (files.Any(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 can add this path to a list and then return all dbPaths to the client if require 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 error"); }}
After this modification, let’s change the client-side. First, we need to modify the input type file control by adding the multiple
attribute:
<input type="file" #file placeholder="Choose file" (change)="uploadFile(file.files)" style="display:none;" multiple>
After that, we are going to modify the uploadFile
function:
uploadFile = (files) => { if (files.length === 0) { return; } let filesToUpload : File[] = files; const formData = new FormData(); Array.from(filesToUpload).map((file, index) => { return formData.append('file'+index, file, file.name); }); this.http.post('https://localhost:5001/api/upload', formData, {reportProgress: true, observe: 'events'}) .subscribe( {next: (event) => { if (event.type === HttpEventType.UploadProgress) this.progress = Math.round(100 * event.loaded / event.total); else if (event.type === HttpEventType.Response) { this.message = 'Upload success.'; this.onUploadFinished.emit(event.body); } }, error: (err: HttpErrorResponse) => console.log(err) });}
One interesting thing to pay attention to is the use of the Array.from()
function. Even though the files
variable contains all the selected files, it is not an array. So, in order to use the map
function, 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. Now you can test your code and check that your files are uploaded.
Conclusion
In this article, we have learned:
- How to code our server-side action to handle file uploading
- The way to create an upload component in our Angular application
- How to use uploaded files in the Angular application
In the next article, you can read how to Download Files with ASP.NET Core Web API and Angular.
FAQs
How do I upload files using net core API and angular? ›
- Create service.
- Create component for uploading files from Angular.
- CSS changes for the component.
- Add method to handle file input.
- The final component class.
- Create a new .NET Core Web API.
- Install the following NuGet Packages.
- Create the following file entities.
- Next, DbContextClass.cs class inside the Data folder. ...
- Create IFileService and FileService files.
- Create FilesController.cs inside controller section.
- CORS Policy. Now use this CORS policy inside the Configure method. ...
- Now Create a Model FileModel. cs inside the Model folder.
- Model. We will be able to access values sent through HttpRequest using Model Binding. ...
- App.js.
- Overview.
- Web API for File Upload & Storage.
- Setup Angular 8 Project.
- Angular 8 App for upload File.
- Set up App Module.
- Add Bootstrap to the project.
- Create Angular Service for Upload Multiple Files.
- Create Angular Component for Upload Multiple Files.
Use the Angular CLI command ng g cl to create a new class that represents a file to upload. You can create a folder named file-upload at the same time you create the FileToUpload class. The FileToUpload class will be created in this new folder. Open the newly generated file-to-upload.
How do I upload files to .NET core 3.1 and Angular 9? ›- Step 1 - Create a Database Table.
- Step 2 - Create a Web API Project. ...
- Step 6 - Create an Angular application for building the UI Application. ...
- Step 7 - Installing file-server.
- Step 8 - Create a component and service.
- Step 12 - Write HTML code in the upload-download.component.
- MVC 4 Project window:
- Select "Web API" and click on the "OK" button. ...
- And write this code in this file: ...
- Click on the "Browse" button.
- Select one image and click on the "Open" button. ...
- Now click on the "Upload" button.
- Now it shows the path where the selected file is saved.
To attach a file, you must include it with the Body as form-data. Once you are in the Body → form-data fields, you must enter a KEY . This should be “file” or whichever value you specified in the @RequestPart(“[value]”) . After doing so, a dropdown will appear that gives you the option of Text or File.
How do I upload a file to API response? ›In React file upload is implemented by using the HTML input element and some JavaScript to make a POST/PUT request to the server with the FormData that contains the selected files. Your server will then need to process multipart form data to accept file uploads. You can use Multer in Node.
How to upload multiple files in Web API C#? ›...
Add the following code:
- @{
- ViewBag. ...
- }
- @using (Html. ...
- {
- <h3>Upload Multiple files </h3>
- <input type="file" name="images" value="" multiple="multiple" />
How do I upload files to an FTP server using .NET core? ›
- string PureFileName = new FileInfo("TotalAmount"). Name;
- FtpWebRequest request = (FtpWebRequest) WebRequest. Create(uploadUrl);
- request. Method = WebRequestMethods. ...
- // This example assumes the FTP site uses anonymous logon.
- request. ...
- request. ...
- request. ...
- request.
Use the File transfer REST API to upload and download files using HTTP or HTTPS as the transport protocol and to list the contents of a directory. Uploads a file to any back-end application that supports REST APIs over HTTP or HTTPS protocol.
How does angular handle bulk data? ›- Step 3: Add the Syncfusion grids package. ...
- Step 4: Register Grid module. ...
- Step 5: Add CSS reference. ...
- Step 6: Add the Data Grid component. ...
- Step 7: Bind 1 million generated data points to Data Grid. ...
- Step 8: Module injection. ...
- Step 9: Run the application.
- Create a new angular app using following command- ng new angular-file-upload.
- Move inside the app by using cd command- cd src/app/
- Generate new component file-upload- ng g c file-upload/
- Open src/app folder and start editing app. ...
- Create a service for file-upload component via command- ng g s file-upload/
- Step 1 – Initializing your Angular 14 Project & Creating the Bare-Bones Artifacts. ...
- Step 2 – Importing HttpClientModule. ...
- Step 3 – Adding Bootstrap 4. ...
- Step 4 – Implementing the Angular 14 Multiple File Upload Service. ...
- Step 5 – Creating our Angular 14 UI for Upload Multiple Files. ...
- Step 6 – Running your Angular 14 App.
The updated Angular project template provides a convenient starting point for ASP.NET Core apps using Angular and the Angular CLI to implement a rich, client-side user interface (UI). The template is equivalent to creating an ASP.NET Core project to act as an API backend and an Angular CLI project to act as a UI.
How does Angular integrate with net core? ›- In Solution Explorer, right-click the ASP.NET Core project and choose Add > Project Reference.
- Select the Angular project and choose OK.
- Right-click the ASP.NET Core project in Solution Explorer and choose Unload Project.
...
Add the following code:
- @{
- ViewBag. Title = "Upload the file and display the uploaded image";
- }
- @using (Html. ...
- {
- <div>
- Select Image.
- <input type="file" name="file" />
- Create a SOAP project in SOAPUI with the downloaded . wsdl file.
- Enter Login details.
- Give all necessary field values.
- Copy & Paste your binary data into Document -> FileContent -> BinaryObject as shown in the below file.
- Run your project.
- Check the response.
There is an XSS (cross-site scripting) vulnerability present in the file upload functionality. Someone can upload a file with a malicious filename, which contains JavaScript code, which would result in XSS.
What is HttpPostedFileBase? ›
The HttpPostedFileBase class is an abstract class that contains the same members as the HttpPostedFile class. The HttpPostedFileBase class lets you create derived classes that are like the HttpPostedFile class, but that you can customize and that work outside the ASP.NET pipeline.
How to send PDF file to Web API C#? ›- Mvc pdf file upload in MVC C#
- Send uploaded file from one sever to third party api in nodejs.
- How to preview PDF file in jsf before upload.
- Converting the web application code in windows form application code.
- Accessing the uploaded file using apicontroller.
- Browsing WEB API in IIS.
...
Add the following code:
- @{
- ViewBag. ...
- }
- @using(Html. ...
- {
- <h2>Export the Excel file in web API Application</h2><br />
- Start Visual Studio 2012.
- Select "File"->"New"->"Project".
- On the template window select "Installed" -> "Template" -> "Other Languages" -> "Visual C#" -> "Web".
- Now choose "ASP. NET MVC4 Web Application" and change the name to "CodeHtml".
- Click on the "OK" button.
HTTP Request action allows you to upload files on a specified service.
What is the best way to upload files? ›Uploading files to cloud storage is a great way to transfer large files such as photos and video. Popular cloud service providers like Google Drive, Files.com, ExaVault, Dropbox, and OneDrive offer mountains of online storage. Each of these products is accessible with more than enough space to cover most file types.
How to send JSON file to API? ›To post JSON to a REST API endpoint, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the POST message. You must also specify the data type using the Content-Type: application/json request header.
How will you implement file uploading in angular reactive form? ›- Creating the Form. First let's create the sign-up form: ...
- Creating the File Upload Component. Let's continue with the file upload component: ...
- Creating a Custom Form Control. At this point, we have a problem. ...
- Creating a Custom Validation. ...
- Send it to the Server. ...
- Room for Improvement. ...
- The Server Endpoint.
for the second key select the attachment you want to upload, set the content type as application/octet-stream and the structure of the name of the key should be attach-fieldname in this case attach-z2AF_Act_Attachment_1, the field it's very important always use attach- and then the exact name of the attachment field ...
How to pass data from web API to Angular? ›First, you have to create a folder then open it in VS Code. Open the terminal and run the command npm init. Fill in all the details and after complete this notification, you have to create a file where you have to create API and a query. To post the data you need to press the click button.
How to connect Angular with NET web API? ›
Create a new Angular project with CLI command. Now start and switch to Visual Studio Code. As you know SRC folder is a source folder where we write our code to fetch data from Asp.Net Web API. Click on SRC folder to view the default internal content SRC folder.
How to connect WebAPI to Angular? ›Open Visual Studio >> File >> New >> Project >> Select Web Application. After that click OK and you will see the templates. Select the Web API template. Click OK.
How to send file to API in Angular? ›- Create a new angular app using following command- ng new angular-file-upload.
- Move inside the app by using cd command- cd src/app/
- Generate new component file-upload- ng g c file-upload/
- Open src/app folder and start editing app. ...
- Create a service for file-upload component via command- ng g s file-upload/
- Step 1: Define AngularJS Application. var app = angular.module("AngularApp", []);
- Step 2: Define “uploadFiles” directive. ...
- Step 3: Define angular Controller. ...
- Step 4: HTML Markup. ...
- Step 5: Web API Controller.
To send data to the REST API server, you must make an HTTP POST request and include the POST data in the request's body. You also need to provide the Content-Type: application/json and Content-Length request headers.
How to transfer large data using REST API? ›- Before You Begin.
- Segmenting the Large File.
- Requesting an Authentication Token.
- Creating a Container.
- Uploading the Segmented Files.
- Creating a Manifest File.
- Uploading the Manifest File.
- Checking the Size of the Large Object.