In my previous article we discussed the different options to implement file upload for cloud applications.
In this article I want to provide you an example of how to implement a file upload through a middleware.:
Example: File Upload to Azure Blog Storage using Angular and ASP.NET Core
We will scaffold our application using the Angular template which is part of the .NET-Core CLI and create a component using the Angular CLI.
Prerequisites
- Node.js and npm
- .NET Core 2.1 SDK
- Angular CLI
- Azure Storage Account *
* You can either manually create the Storage Account within the Azure Portal or by using the following ARM Template:
Scaffold the project
To scaffold the project we use the dotnet new command:
dotnet new angular --name file-upload
Implement the middleware
To store the uploaded files to Azure Blob Storage we need to specify the connection string within the appsettings.json
:
"ConnectionStrings": { "StorageAccount": "UseDevelopmentStorage=true" },
If you don’t have the Azure Storage Emulator installed you have to replace the value with an actual Azure Storage Account connection string.
Install WindowsAzure.Storage NuGet Package
You can install the NuGet package using the following command:
dotnet add package WindowsAzure.Storage
File upload implementation
We will implement the file upload in a new Controller called AssetController
. The controller only exposes a single method called UploadAssetAsync
which takes an IFormFile
with the name asset
(note: IFormFile is suitable for uploading small files, if you have to deal with large files you have to consider implementing streaming or uploading the files directly from the client to a data store. Further information here.).
The UploadAssetAsync
method uploads the passed file to the previous specified Azure Blob Storage and returns the URI of the new blob:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.WindowsAzure.Storage; namespace file_upload.Controllers { [Route("api/[controller]")] public class AssetController : Controller { private readonly IConfiguration _configuration; public AssetController(IConfiguration config) { _configuration = config; } [HttpPost] public async Task UploadAssetAsync([FromForm] IFormFile asset) { CloudStorageAccount storageAccount = null; if (CloudStorageAccount.TryParse(_configuration.GetConnectionString("StorageAccount"), out storageAccount)) { var client = storageAccount.CreateCloudBlobClient(); var container = client.GetContainerReference("fileupload"); await container.CreateIfNotExistsAsync(); var blob = await container.GetBlobReferenceFromServerAsync(asset.FileName); await blob.UploadFromStreamAsync(asset.OpenReadStream()); return Ok(blob.Uri); } return StatusCode(StatusCodes.Status500InternalServerError); } } }
Disable HttpsRedirection in Development
Before we can run the application we should disable the Https redirection for the development environment (note: you can also install a localhost certificate). Otherwise we will get a warning that the site is not secure. This can be done by replacing the following line in the Configure
method within the Startup.cs
app.UseHttpsRedirection();
with:
if (!env.IsDevelopment()) { app.UseHttpsRedirection(); }
Implement the frontend
We will implement the file upload in a new component. To create the new component we use the Angular CLI:
ng g component fileUpload
Note: Ensure you invoke the CLI commands within the ClientApp
directory.
Configure Routing
Now we add routing to our new component within the app.module.ts
:
{ path: 'file-upload', component: FileUploadComponent },
Then we add a link to the component inside the nav-menu.component.html:
<li> <a> <span class='glyphicon glyphicon-cloud-upload'></span> File Upload </a> </li>
Install PrimeNG
We use the PrimeNG NPM package to implement the file upload:
npm install primeng --save
Add the file upload
The last thing we have to do is to add the file upload to the file-upload.component.html
. The name
attribute value must match with the IFormFile
parameter name in the middleware (in our case “asset“). The url is /api/Asset
which is the address of the UploadAssetAsync middleware web method:
<p-fileUpload #fubauto mode="basic" name="asset" url="/api/Asset" maxFileSize="1000000" (onUpload)="uploadFile($event)" auto="true" chooseLabel="Browse"></p-fileUpload>
That is it. We don’t need to implement any further upload mechanism. To start the application we can use the dotnet CLI:
dotnet run
The source code can be found in my GitHub repository.