Integrating Azure Blob Storage with ABP.IO Framework

Integrating Azure Blob Storage with ABP.IO Framework

Integrating Azure Blob Storage with ABP.IO Framework

A highly scalable cloud storage option for storing substantial volumes of unstructured data is Azure Blob Storage. When paired with the ABP.IO Framework, it provides a reliable and effective way to handle files in your online apps. We’ll walk you through the process of connecting Azure Blob Storage with an ABP.IO-based application in this blog post, replete with sample code.

What is Azure Blob Storage?

Microsoft Azure’s Azure Blob Storage is a cloud-based service intended for storing substantial volumes of unstructured data, such text or binary data. The acronym for “Blob” is “Binary Large Object.” It is suited for a broad range of tasks, including as providing pictures or documents directly to a browser, storing files for distributed access, and streaming music and video. It is extremely scalable, durable, and secure, and is optimized for storing huge volumes of data.

Key Components

  1. Storage Account: A container that holds all Azure Storage data objects, including blobs, files, queues, and tables.
  2. Container: A container organizes a set of blobs, similar to a directory in a file system.
  3. Blob: The actual data object stored in a container. There are three types:
  • Block blobs: Store text and binary data, optimal for large files.
  • Append blobs: Ideal for append operations, suitable for logging.
  • Page blobs: Used for random read/write operations, often used for VHDs.

Key Features

  • Scalability: Handles large amounts of data and high throughput.
  • Durability and Availability: Offers multiple redundancy options (LRS, ZRS, GRS, RA-GRS).
  • Security: Provides encryption, shared access signatures (SAS), and integration with Azure Active Directory.
  • Cost-Effectiveness: Various storage tiers (Hot, Cool, Archive) optimize costs based on access frequency.
  • Access and Management: Accessible via Azure Storage Explorer, REST APIs, SDKs, and is compatible with Hadoop Distributed File System (HDFS).

Common Use Cases

  • Backup and Restore: For data and application backups.
  • Content Storage and Delivery: For static content like images and videos.
  • Big Data and Analytics: For storing large datasets.
  • Disaster Recovery: For geographically redundant storage.
  • Streaming Media: For storing and streaming multimedia files.

Integrating Azure Blob Storage with ABP.IO Framework

Now, let’s walk through the process of integrating Azure Blob Storage with an ABP.IO-based application, complete with code examples.

Prerequisites

  1. An active Azure account.
  2. An ABP.IO application. If you don’t have one, follow the ABP.IO documentation to create your project.
  3. Azure Storage account and Blob container. Follow the Azure Blob Storage documentation to set these up.

Step 1: Install Azure Storage NuGet Package

First, install the Azure.Storage.Blobs NuGet package:

dotnet add package Azure.Storage.Blobs

Step 2: Configure Azure Blob Storage in Your ABP.IO Application

Add your Azure Blob Storage settings to the appsettings.json file:

{
  "AzureBlobStorage": {
    "AccountName": "your-storage-account-name",
    "AccountKey": "your-storage-account-key",
    "ContainerName": "your-container-name"
  }
}

Step 3: Create a Service for Blob Storage Operations

Create a service to handle Azure Blob Storage operations:

BlobStorageService.cs

using Azure.Storage.Blobs;
using Microsoft.Extensions.Configuration;
using System.IO;
using System.Threading.Tasks;
public class BlobStorageService
{
    private readonly BlobServiceClient _blobServiceClient;
    private readonly string _containerName;
    public BlobStorageService(IConfiguration configuration)
    {
        var accountName = configuration["AzureBlobStorage:AccountName"];
        var accountKey = configuration["AzureBlobStorage:AccountKey"];
        _containerName = configuration["AzureBlobStorage:ContainerName"];
        var credentials = new StorageSharedKeyCredential(accountName, accountKey);
        var blobUri = new Uri($"https://{accountName}.blob.core.windows.net");
        _blobServiceClient = new BlobServiceClient(blobUri, credentials);
    }
    public async Task<string> UploadFileAsync(Stream fileStream, string fileName)
    {
        var blobContainerClient = _blobServiceClient.GetBlobContainerClient(_containerName);
        var blobClient = blobContainerClient.GetBlobClient(fileName);
        await blobClient.UploadAsync(fileStream, true);
        return blobClient.Uri.ToString();
    }
    public async Task<Stream> DownloadFileAsync(string fileName)
    {
        var blobContainerClient = _blobServiceClient.GetBlobContainerClient(_containerName);
        var blobClient = blobContainerClient.GetBlobClient(fileName);
        var response = await blobClient.DownloadAsync();
        return response.Value.Content;
    }
}

Step 4: Register BlobStorageService in Dependency Injection

In your module class (typically *.Module.cs), register the BlobStorageService in the ConfigureServices method:

public override void ConfigureServices(ServiceConfigurationContext context)
{
    var configuration = context.Services.GetConfiguration();
    context.Services.AddSingleton<BlobStorageService>(provider => new BlobStorageService(configuration));
}

Step 5: Create Application Service for File Operations

Create an application service to handle file uploads and downloads.

IFileAppService.cs

using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
public interface IFileAppService
{
    Task<string> UploadFileAsync(IFormFile file);
    Task<FileResult> DownloadFileAsync(string fileName);
}

FileAppService.cs

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.IO;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
public class FileAppService : ApplicationService, IFileAppService
{
    private readonly BlobStorageService _blobStorageService;
    public FileAppService(BlobStorageService blobStorageService)
    {
        _blobStorageService = blobStorageService;
    }
    [HttpPost]
    public async Task<string> UploadFileAsync(IFormFile file)
    {
        if (file == null || file.Length == 0)
            throw new UserFriendlyException("File cannot be empty");
        using (var stream = new MemoryStream())
        {
            await file.CopyToAsync(stream);
            stream.Position = 0;
            var fileName = Path.GetFileName(file.FileName);
            return await _blobStorageService.UploadFileAsync(stream, fileName);
        }
    }
    [HttpGet]
    public async Task<FileResult> DownloadFileAsync(string fileName)
    {
        var stream = await _blobStorageService.DownloadFileAsync(fileName);
        return new FileStreamResult(stream, "application/octet-stream")
        {
            FileDownloadName = fileName
        };
    }
}

Step 6: Create Controller for File Operations

Expose the file operations via HTTP endpoints.

FileController.cs

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc;
[Route("api/files")]
public class FileController : AbpController
{
    private readonly IFileAppService _fileAppService;
    public FileController(IFileAppService fileAppService)
    {
        _fileAppService = fileAppService;
    }
    [HttpPost("upload")]
    public async Task<IActionResult> Upload(IFormFile file)
    {
        var result = await _fileAppService.UploadFileAsync(file);
        return Ok(result);
    }
    [HttpGet("download")]
    public async Task<IActionResult> Download(string fileName)
    {
        var file = await _fileAppService.DownloadFileAsync(fileName);
        return file;
    }
}

Conclusion

By following these steps, you have successfully integrated Azure Blob Storage with your ABP.IO Framework application. This setup allows you to leverage Azure’s scalable and reliable storage solution for managing files within your application. You can extend this implementation by adding more functionalities such as file deletion, listing files, and advanced error handling.

Share this post

Leave a Reply

Your email address will not be published. Required fields are marked *