Skip to main content

Storage Module - Quick Start

Maturity: Beta

This module is actively being improved. Breaking changes are unlikely but possible.

Unified file storage API for Azure Blob, AWS S3, or local filesystem. All operations run entirely within your application.

Providers

The Storage module supports multiple providers. Choose the one that matches your environment:

Provider 1: Azure Blob Storage

Step 1: Install Package

dotnet add package PrimusSaaS.Storage

Step 2: Configure in Program.cs

using Primus.Storage;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddPrimusStorage(storage => {
storage.UseAzureBlob(opts => {
opts.ConnectionString = builder.Configuration["Azure:StorageConnectionString"];
opts.ContainerName = "uploads";
});
});

var app = builder.Build();
app.MapControllers();
app.Run();

Step 3: Configure appsettings.json

{
"Azure": {
"StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=..."
}
}
How to Get Azure Connection String

Azure Portal:

  1. Go to portal.azure.com
  2. Storage Account > Security + networking > Access keys
  3. Copy Connection string (Key 1 or Key 2)

Step 4: Create Storage Controller

Create Controllers/StorageController.cs:

using Microsoft.AspNetCore.Mvc;
using Primus.Storage;

namespace YourApp.Controllers;

[ApiController]
[Route("api/[controller]")]
public class StorageController : ControllerBase
{
private readonly IStorageProvider _storage;

public StorageController(IStorageProvider storage)
{
_storage = storage;
}

[HttpPost("upload")]
public async Task<IActionResult> Upload(IFormFile file)
{
var path = $"documents/{Guid.NewGuid()}/{file.FileName}";
using var stream = file.OpenReadStream();
await _storage.UploadAsync(path, stream, file.ContentType);
return Ok(new { path });
}

[HttpGet("download/{*path}")]
public async Task<IActionResult> Download(string path)
{
var stream = await _storage.DownloadAsync(path);
return File(stream, "application/octet-stream");
}
}

Step 5: Test Endpoints

curl -X POST http://localhost:5000/api/storage/upload \
-F "file=@test.txt"

Provider 2: AWS S3

Step 1: Install Package

dotnet add package PrimusSaaS.Storage

Step 2: Configure in Program.cs

builder.Services.AddPrimusStorage(storage => {
storage.UseAwsS3(opts => {
opts.AccessKey = builder.Configuration["AWS:AccessKey"];
opts.SecretKey = builder.Configuration["AWS:SecretKey"];
opts.Region = "us-east-1";
opts.BucketName = "my-app-uploads";
});
});

Step 3: Configure appsettings.json

{
"AWS": {
"AccessKey": "AKIA...",
"SecretKey": "..."
}
}
How to Get AWS Credentials

AWS Console:

  1. IAM > Users > Create User (or select existing)
  2. Security credentials > Create access key
  3. Copy Access Key ID and Secret Access Key

Step 4 & 5

(Reuse Controller and Test commands from above - the API is identical)


Provider 3: Local Filesystem

Step 1: Install Package

dotnet add package PrimusSaaS.Storage

Step 2: Configure in Program.cs

builder.Services.AddPrimusStorage(storage => {
storage.UseLocalFileSystem(opts => {
opts.RootPath = "wwwroot/uploads";
});
});

Step 3: Configure appsettings.json

No sensitive secrets needed for local storage. Ensure RootPath directory applies.


Configuration Reference

Azure Blob Options

OptionTypeDescription
ConnectionStringstringAzure Storage Connection String
ContainerNamestringBlob container (folder) name

AWS S3 Options

OptionTypeDescription
AccessKeystringAWS Access Key ID
SecretKeystringAWS Secret Access Key
BucketNamestringS3 Bucket Name
RegionstringAWS Region (e.g., us-east-1)

Local Options

OptionTypeDescription
RootPathstringLocal folder path (absolute or relative)

Examples

Example 1: Pre-signed URLs

var url = await _storage.GetUrlAsync("docs/contract.pdf", TimeSpan.FromMinutes(15));
return Ok(new { downloadUrl = url });

Troubleshooting

Issue: Access Denied

Solution:

  1. AWS: Ensure IAM user has s3:PutObject and s3:GetObject permissions.
  2. Azure: Ensure Connection String allows Read/Write to the container.