Decode.Storage.AzureBlob 3.0.0

dotnet add package Decode.Storage.AzureBlob --version 3.0.0
                    
NuGet\Install-Package Decode.Storage.AzureBlob -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Decode.Storage.AzureBlob" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Decode.Storage.AzureBlob" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Decode.Storage.AzureBlob" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Decode.Storage.AzureBlob --version 3.0.0
                    
#r "nuget: Decode.Storage.AzureBlob, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Decode.Storage.AzureBlob@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Decode.Storage.AzureBlob&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Decode.Storage.AzureBlob&version=3.0.0
                    
Install as a Cake Tool

Decode.Storage.AzureBlob

Azure Blob Storage implementation of IStorageService for the Decode.Storage ecosystem.

📦 Installation

dotnet add package Decode.Storage.AzureBlob

🛠️ Usage

1. Register Services

In your Program.cs or Startup.cs:

using Decode.Storage.AzureBlob.Extensions;

builder.Services.AddAzureBlobStorage(options =>
{
    options.ConnectionString = "UseDevelopmentStorage=true"; // Azure Storage Account connection string
    options.ContainerName = "my-container";                  // Target container
    options.CreateContainerIfNotExists = true;               // Automatically create container on uploads if missing
});

This registration adds both IStorageService and IFileValidator (implemented by FileSignatureValidator) as singletons. IStorageService is a singleton because its constructor builds a BlobServiceClient, which is thread-safe and owns an HTTP connection pool that Microsoft recommends creating once and reusing; it was transient before 2.0.0.

2. Inject and Use in Services

using Decode.Storage.Abstractions;

public class ProfileService
{
    private readonly IStorageService _storage;

    public ProfileService(IStorageService storage)
    {
        _storage = storage;
    }

    public async Task SaveAvatarAsync(Guid userId, Stream content)
    {
        // Uploads the stream directly to Azure Blob container, setting the appropriate Content-Type header.
        string blobUrl = await _storage.UploadAsync($"avatars/{userId}.png", content, "image/png");
    }

    public async Task<StorageFile?> GetAvatarAsync(Guid userId)
    {
        // Downloads the file as a non-buffering stream directly from Azure Blob Storage.
        return await _storage.DownloadAsync($"avatars/{userId}.png");
    }

    public async Task<string> GetTemporaryDownloadUrlAsync(Guid userId)
    {
        // Generates a secure pre-signed SAS URI that expires in 15 minutes.
        // Requires an account key in the connection string — see below.
        return await _storage.GetUrlAsync($"avatars/{userId}.png", DateTimeOffset.UtcNow.AddMinutes(15));
    }
}

SAS generation requires a shared key

GetUrlAsync only signs a URI when expiration is supplied. Signing needs the account key, so the client must have been built from a connection string that carries one. If the account is authenticated any other way — Managed Identity, DefaultAzureCredential, a SAS-only connection string — the Azure SDK cannot sign locally and the call throws:

InvalidOperationException: The BlobClient cannot generate a SAS URI.
Check account keys or authentication configurations.

This is the most common production surprise, because UseDevelopmentStorage=true and full connection strings both work in development while Managed Identity is the usual choice once deployed. With a credential-based client, issue a user delegation SAS through BlobServiceClient.GetUserDelegationKeyAsync directly instead.

Calling GetUrlAsync without expiration returns the plain blob URI and never throws — but that URI only resolves for callers who can authenticate, so it is not a substitute for a signed link on a private container.

📄 License

MIT License.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0 97 9/14/2026
2.1.0 95 9/13/2026
2.0.2 90 9/13/2026
2.0.1 90 9/13/2026
2.0.0 127 7/28/2026
1.0.3 124 6/22/2026