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:
- Go to portal.azure.com
- Storage Account > Security + networking > Access keys
- 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:
- IAM > Users > Create User (or select existing)
- Security credentials > Create access key
- 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
| Option | Type | Description |
|---|---|---|
ConnectionString | string | Azure Storage Connection String |
ContainerName | string | Blob container (folder) name |
AWS S3 Options
| Option | Type | Description |
|---|---|---|
AccessKey | string | AWS Access Key ID |
SecretKey | string | AWS Secret Access Key |
BucketName | string | S3 Bucket Name |
Region | string | AWS Region (e.g., us-east-1) |
Local Options
| Option | Type | Description |
|---|---|---|
RootPath | string | Local 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:
- AWS: Ensure IAM user has
s3:PutObjectands3:GetObjectpermissions. - Azure: Ensure Connection String allows Read/Write to the container.