File upload through ASP.NET Core middleware

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.


* 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
    public class AssetController : Controller
        private readonly IConfiguration _configuration;
        public AssetController(IConfiguration config)
            _configuration = config;

        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



if (!env.IsDevelopment())

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:

        <span class='glyphicon glyphicon-cloud-upload'></span> File Upload

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" auto="true"

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.

File upload in Cloud Applications: The Options

Almost every web application requires some form of file upload.Ā  You may want to allow a user to upload a profile picture or to import any kind of data.

Multiple ways to implement the file upload

Depending on the size of the files and the regularity of the upload you have two options to implement the upload:

Directly upload the file to a data store

The fastest and resource friendliest way is to directly upload the file from the client to a data store. This typically requires the client to have the security credentials for the data store:

direct_uploadBut giving security credentials to potential untrusted clients isn’t a realistic approach for most web applications. Instead you want to use a token that provides clients restricted access to a specific resource for a limited validity period. This pattern is known as Valet Key pattern.

Upload the file through a middleware

The second option is to upload the file to your middleware (API) which will handle the movement of the data to the data store.


This approach prevents us from exposing any information about the underlying data store to the client. We could even change our Data Store (e. g. from Azure Blob Storage to Azure File Storage) without updating the client.

The downside is that it absorbs valuable resources from our middleware like compute, memory and bandwidth.