Blob Storage is a feature in Microsoft Azure that lets developers store unstructured data in Microsoft's cloud platform. This data can be accessed from anywhere in the world and can include audio, video, and text files. Blobs are grouped into "containers" that are tied to user accounts. Blobs can be manipulated with .NET or .NET Core code.
In this article, we will see how to create Azure Blob Storage and create services in ASP.NET Core Web API to upload, list, download, and delete files from Azure Blob Storage. We will create an Angular 8 application to perform these operations from the client side.
Create Blob storage in Azure portal
It is easy to create a blob storage in Azure portal. Choose “Storage account” and give the required information. Choose a unique name for the storage account.
Click the “Review + create” button to validate and then, click the “Create” button to proceed.
Currently, there are four types of services available in the storage account.
We can choose “Blobs” and create a container to store our unstructured data.
We can choose the access level as “Private” so that nobody will access without enough privileges. You can click “Access keys” tab and choose connection string and keep that in a secure place for future usage. We will use this connection string in our ASP.NET Core project later.
Create a Web API service in ASP.NET Core project
We can create a new ASP.NET Web API project in Visual Studio and create all services for file operations.
Please choose "API" template.
Our project will be ready in a few moments.
We can keep the blob storage connection string and container name in the appsettings.js file. We will fetch these values from the settings file using a configuration class file. We can create a config file “MyConfig.cs” to access these configuration values.
- namespace BlobStorageASP.NETCore
- {
- public class MyConfig
- {
- public string StorageConnection { get; set; }
- public string Container { get; set; }
- }
- }
I have created two properties for connection string and container name respectively inside this class file.
We can add storage connection string and container name in the appsettings.js file as well.
- {
- "Logging": {
- "LogLevel": {
- "Default": "Warning"
- }
- },
- "MyConfig": {
- "StorageConnection": "DefaultEndpointsProtocol=https;AccountName=sarathstorageaccount;AccountKey=G176lDXKsN1joI6yL9G/JuC4MCMdMSZNEJBzIYZnhcQsjkRd8MCfoxREiqguuo5kON2BcIpSHXSqnVDZ9+7OAQ==;EndpointSuffix=core.windows.net",
- "Container": "sarathcontainer"
- },
- "AllowedHosts": "*"
- }
Modify the Startup.cs class with below changes. We have added dependency for MyConfig class. We have enabled CORS in this class too because we will consume these Web API services in Angular 8 application.
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.DependencyInjection;
-
- namespace BlobStorageASP.NETCore
- {
- public class Startup
- {
- public Startup(IConfiguration configuration)
- {
- Configuration = configuration;
- }
-
- public IConfiguration Configuration { get; }
-
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
- services.AddCors(c =>
- {
- c.AddPolicy("AllowOrigin", options => options.WithOrigins("http://localhost:4200"));
- });
- services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
- }
-
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- app.UseCors(options => options.WithOrigins("http://localhost:4200"));
- app.UseMvc();
- }
- }
- }
We can create “BlobStorage” controller now. We will use scaffolding template for creating this Web API controller.
Right-click the Controllers folder and choose “Add New Scaffolded Item”.
Choose the “API” tab and select “API Controller with read/write actions” option.
Install “WindowsAzure.Storage” NuGet package in the project.
Copy the below code and paste inside this Controller class.
BlobStorageController.cs
I have added the code for uploading, listing, downloading, and deleting files from Azure Blob Storage. All the code is self-explanatory.
We have completed the API project coding part. We can check these services using Postman or any other tools.
Create an Angular 8 client application using CLI
Create a new Angular 8 application using the below CLI command.
ng new BlobStorageAngular8
We need “bootstrap”, “font-awesome", and “file-save” libraries in this project. We can install these libraries one by one.
We can import “bootstrap” and “font-awesome” libraries inside the style.css class in the root folder of “src” folder. This way, we can use these libraries in the entire project without further references.
-
- @import "~bootstrap/dist/css/bootstrap.css";
- @import "~font-awesome/css/font-awesome.css";
Let us add “HttpClientModule” and “FormsModule” in app.module.ts file. We will use both these modules in our project.
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { AppComponent } from './app.component';
-
- import { HttpClientModule } from '@angular/common/http';
- import { FormsModule } from '@angular/forms';
-
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- HttpClientModule,
- FormsModule
- ],
- providers: [],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
We can modify the app.component.ts component file with the below code.
- import { Component, OnInit } from '@angular/core';
- import { HttpClient } from '@angular/common/http';
- import { saveAs } from 'file-saver';
- declare var require: any;
-
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent implements OnInit {
- constructor(private http: HttpClient) { }
- files: string[] = [];
- fileToUpload: FormData;
- fileUpload: any;
- fileUpoadInitiated: boolean;
- fileDownloadInitiated: boolean;
- private baseUrl = 'http://localhost:4000/api/blobstorage';
-
- ngOnInit(): void {
- this.showBlobs();
- }
-
- showBlobs() {
- this.http.get<string[]>(this.baseUrl + '/listfiles').subscribe(result => {
- this.files = result;
- }, error => console.error(error));
- }
-
- addFile() {
- if (!this.fileUpoadInitiated) {
- document.getElementById('fileUpload').click();
- }
- }
- handleFileInput(files: any) {
- let formData: FormData = new FormData();
- formData.append("asset", files[0], files[0].name);
- this.fileToUpload = formData;
- this.onUploadFiles();
- }
-
- onUploadFiles() {
- if (this.fileUpoadInitiated) {
- return;
- }
- this.fileUpoadInitiated = true;
- if (this.fileToUpload == undefined) {
- this.fileUpoadInitiated = false;
- return false;
- }
- else {
- return this.http.post(this.baseUrl + '/insertfile', this.fileToUpload)
- .subscribe((response: any) => {
- this.fileUpoadInitiated = false;
- this.fileUpload = '';
- if (response == true) {
- this.showBlobs();
- }
- else {
- alert('Error occured!');
- this.fileUpoadInitiated = false;
- }
- },
- err => console.log(err),
- );
-
- }
- }
- downloadFile(fileName: string) {
- this.fileDownloadInitiated = true;
- return this.http.get(this.baseUrl + '/downloadfile/' + fileName, { responseType: "blob" })
- .subscribe((result: any) => {
- if (result.type != 'text/plain') {
- var blob = new Blob([result]);
- let saveAs = require('file-saver');
- let file = fileName;
- saveAs(blob, file);
- this.fileDownloadInitiated = false;
- }
- else {
- this.fileDownloadInitiated = false;
- alert('File not found in Blob!');
- }
- }
- );
- }
- deleteFile(fileName: string) {
- var del = confirm('Are you sure want to delete this file');
- if (!del) return;
- this.http.get(this.baseUrl + '/deletefile/' + fileName).subscribe(result => {
- if (result != null) {
- this.showBlobs();
- }
- }, error => console.error(error));
- }
- }
We have added all the logic for file operations with Blob Storage in this component.
Modify the corresponding HTML and CSS files for this component as well.
app.component.html
- <div style="text-align:center; margin-top: 20px;">
- <h4>
- Upload, Download and Delete Blob Files using ASP.NET Core and Angular 8
- </h4>
- </div>
-
- <div class="blobstorage-section">
- <i class="fa fa-plus fa-2x" style="cursor: pointer; color: darkslateblue;" (click)="addFile()"></i> Add new files to Blob
- <input style="display: none;" type="file" id="fileUpload" #selectedFile [(ngModel)]="fileUpload" (click)="selectedFile.value = null" value="" (change)="handleFileInput($event.target.files)" />
- <table style="margin-top: 20px;">
- <tr>
- <th class="column1">Uploaded Files</th>
- <th class="column2" style="text-align:center;">Download</th>
- <th class="column3" style="text-align:center;">Delete</th>
- </tr>
- <tr *ngFor="let file of files">
- <td class="column1">{{file}}</td>
- <td class="column2" style="text-align:center;cursor: pointer;" (click)="downloadFile(file)"><i class="fa fa-download"></i></td>
- <td class="column3" style="text-align:center;" (click)="deleteFile(file)">
- <img alt="Group Audit" src="../assets/icon-download.png" />
- </td>
- </tr>
- </table>
- </div>
app.component.css
- .blobstorage-section {
- font-family: Calibri;
- box-shadow: 0 1px 4px 0 #9b9b9b;
- background-color: #ffffff;
- margin: auto;
- margin-top: 50px;
- padding: 30px;
- width: 50%;
- }
-
- .column1{
- width:450px;
- }
- .column2{
- width:100px;
- }
- .column3{
- width:100px;
- }
- .blobstorage-section th {
- font-family: Calibri;
- font-size: 14px;
- font-weight: bold;
- font-style: normal;
- font-stretch: normal;
- line-height: 1.57;
- letter-spacing: normal;
- color: #333333;
- border-right: 1px solid #d7d7d7;
- border-bottom: 1px solid #d7d7d7;
- }
-
- .blobstorage-section th i {
- font-family: Calibri;
- font-size: 16px;
- }
-
- .blobstorage-section tbody tr td {
- border-right: 1px solid #d7d7d7;
- border-bottom: 1px solid #d7d7d7;
- }
-
- .blobstorage-section tbody tr td a {
- font-family: Calibri;
- font-size: 15px;
- font-weight: normal;
- font-style: normal;
- font-stretch: normal;
- line-height: 1.2;
- letter-spacing: normal;
- color: #0091da;
- text-decoration: underline;
- }
-
- .blobstorage-section tr td img:hover {
- cursor: pointer;
- }
We have completed the entire project. Run both, ASP.NET Core project and Angular project, now.
Click the (+) button to add new files.
You can download/delete these files using corresponding buttons in the grid.
Conclusion
In this post, we have seen how to upload, list, download and delete files from Azure Blob storage using ASP.NET Core API project and we have consumed these services in an Angular 8 client project. You can download the source code and check from your side. Please feel free to contact me with your valuable comments on this article.