Introduction
Azure Blob Storage is a cloud storage solution from Microsoft Azure that makes it easy to store and retrieve files such as images, documents, and videos. This article walks through integrating Azure Blob Storage with an ASP.NET Core 8 MVC application and implementing upload, download, delete, and listing operations.
Set Up Azure Blob Storage
Step 1: Create a Storage Account
Create an Azure Storage Account first. If you need help, refer to the earlier article on creating a storage account. After the storage account is ready, open the Access Key section and copy the connection string.

Step 2: Configure appsettings.json
Add the storage connection string to your ASP.NET Core application settings.
{
"ConnectionStrings": {
"StorageAccount": "YourConnectionStringHere"
}
}Step 3: Register Blob Service Client
Register the BlobServiceClient in Program.cs so it can be injected into controllers.
using Azure.Storage.Blobs;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
// Register blob service client by reading StorageAccount connection string from appsettings.json
builder.Services.AddSingleton(x => new BlobServiceClient(builder.Configuration.GetConnectionString("StorageAccount")));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();Registering the BlobServiceClient as a singleton makes it available throughout the application's lifetime and allows the controller to work with Azure Blob Storage efficiently.
Blob Storage Controller
Create a dedicated BlobStorageController to manage Azure Blob Storage operations.
Before you begin, install the Azure.Storage.Blobs NuGet package.

Controller Fields and Constructor
private const string ContainerName = "myfiles";
public const string SuccessMessageKey = "SuccessMessage";
public const string ErrorMessageKey = "ErrorMessage";
private readonly BlobServiceClient _blobServiceClient;
private readonly BlobContainerClient _containerClient;
public BlobStorageController(BlobServiceClient blobServiceClient)
{
_blobServiceClient = blobServiceClient;
_containerClient = _blobServiceClient.GetBlobContainerClient(ContainerName);
_containerClient.CreateIfNotExists();
}The controller initializes the blob client and container client, and creates the container if it does not already exist.

Upload Files
public IActionResult Upload()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Upload(IFormFile file)
{
try
{
var blobClient = _containerClient.GetBlobClient(file.FileName);
await blobClient.UploadAsync(file.OpenReadStream(), true);
TempData[SuccessMessageKey] = "File uploaded successfully.";
}
catch (Exception ex)
{
TempData[ErrorMessageKey] = "An error occurred while uploading the file: " + ex.Message;
return View();
}
return RedirectToAction("Index");
}The upload flow reads the selected file as an IFormFile, uploads it to the blob container, and stores a success or error message in TempData.

Retrieve Files
public async Task<IActionResult> Index()
{
var blobs = new List<string>();
await foreach (var blobItem in _containerClient.GetBlobsAsync())
{
blobs.Add(blobItem.Name);
}
return View(blobs);
}This action retrieves all blob names from the container and passes them to the view.

Download Files
public async Task<IActionResult> Download(string fileName)
{
try
{
var blobClient = _containerClient.GetBlobClient(fileName);
var memoryStream = new MemoryStream();
await blobClient.DownloadToAsync(memoryStream);
memoryStream.Position = 0;
var contentType = blobClient.GetProperties().Value.ContentType;
return File(memoryStream, contentType, fileName);
}
catch (Exception ex)
{
TempData[ErrorMessageKey] = "An error occurred while downloading the file: " + ex.Message;
return RedirectToAction("Index");
}
}Delete Files
public async Task<IActionResult> Delete(string fileName)
{
try
{
var blobClient = _containerClient.GetBlobClient(fileName);
await blobClient.DeleteIfExistsAsync();
TempData[SuccessMessageKey] = "File deleted successfully.";
}
catch (Exception ex)
{
TempData[ErrorMessageKey] = "An error occurred while deleting the file: " + ex.Message;
}
return RedirectToAction("Index");
}Create the Views
The article uses two views: Index.cshtml and Upload.cshtml.
Index.cshtml
@model List<string>
@{
ViewData["Title"] = "Blob Storage";
var errorMessage = TempData[AspNetMVCWithAzure.Controllers.BlobStorageController.ErrorMessageKey] as string;
var successMessage = TempData[AspNetMVCWithAzure.Controllers.BlobStorageController.SuccessMessageKey] as string;
}
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-danger mb-2" role="alert">
@errorMessage
</div>
}
@if (!string.IsNullOrEmpty(successMessage))
{
<div class="alert alert-success mb-2" role="alert">
@successMessage
</div>
}
<a asp-controller="BlobStorage" asp-action="Upload" class="btn btn-primary">Upload New File</a>
<table class="table table-bordered mt-3">
<thead class="thead-dark">
<tr>
<th>File Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@if (Model.Count > 0)
{
foreach (var fileName in Model)
{
<tr>
<td>@fileName</td>
<td>
<a asp-controller="BlobStorage" asp-action="Download" asp-route-fileName="@fileName" class="btn btn-success">Download</a>
<a asp-controller="BlobStorage" asp-action="Delete" asp-route-fileName="@fileName" class="btn btn-danger">Delete</a>
</td>
</tr>
}
}
else
{
<tr>
<td colspan="2" class="text-center"><b>No files found.</b></td>
</tr>
}
</tbody>
</table>Upload.cshtml
<h2>Upload File</h2>
@{
ViewData["Title"] = "Upload New File";
var errorMessage = TempData[AspNetMVCWithAzure.Controllers.BlobStorageController.ErrorMessageKey] as string;
var successMessage = TempData[AspNetMVCWithAzure.Controllers.BlobStorageController.SuccessMessageKey] as string;
}
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-danger mb-2" role="alert">
@errorMessage
</div>
}
@if (!string.IsNullOrEmpty(successMessage))
{
<div class="alert alert-success mb-2" role="alert">
@successMessage
</div>
}
<div class="row">
<div class="col-md-6">
<form method="post" enctype="multipart/form-data" asp-action="Upload">
<div class="row">
<div class="col-md-12">
<label for="file">Select File:</label>
</div>
<div class="col-md-12">
<input type="file" class="form-control-file" id="file" name="file" required>
</div>
</div>
<div class="row mt-3">
<div class="col-md-12">
<button type="submit" class="btn btn-primary">Upload</button>
<a asp-action="Index" class="btn btn-secondary">Back</a>
</div>
</div>
</form>
</div>
</div>Output

Conclusion
In this article, we learned how to integrate Azure Blob Storage with ASP.NET Core 8 MVC using a dedicated BlobStorageController. With this setup, you can efficiently manage files in your web application using Azure Blob Storage.
The original article also links to the source code on GitHub: AspNetMVCWithAzure.
For deployment guidance, the original article references a separate post about deploying a .NET MVC app on Azure App Services.
