Zetian.Storage.AzureBlob 1.0.4

Prefix Reserved
dotnet add package Zetian.Storage.AzureBlob --version 1.0.4
                    
NuGet\Install-Package Zetian.Storage.AzureBlob -Version 1.0.4
                    
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="Zetian.Storage.AzureBlob" Version="1.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zetian.Storage.AzureBlob" Version="1.0.4" />
                    
Directory.Packages.props
<PackageReference Include="Zetian.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 Zetian.Storage.AzureBlob --version 1.0.4
                    
#r "nuget: Zetian.Storage.AzureBlob, 1.0.4"
                    
#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 Zetian.Storage.AzureBlob@1.0.4
                    
#: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=Zetian.Storage.AzureBlob&version=1.0.4
                    
Install as a Cake Addin
#tool nuget:?package=Zetian.Storage.AzureBlob&version=1.0.4
                    
Install as a Cake Tool

Zetian.Storage.AzureBlob - Azure Cloud Storage

NuGet-Version NuGet-Download License

Azure Blob Storage provider for Zetian SMTP Server. Provides enterprise-grade cloud storage with features including hierarchical namespace support, access tier management, soft delete capabilities, Azure AD authentication, lifecycle management, and built-in encryption. Perfect for organizations using Microsoft Azure requiring scalable, secure, and cost-effective message archival with seamless integration into Azure ecosystem.

⚡ Features

  • 📸 Snapshots - Point-in-time recovery
  • 🗑️ Soft Delete - Recover deleted messages
  • 📈 Analytics - Storage analytics and metrics
  • 🌍 Geo-Redundancy - Cross-region replication
  • 🔒 Encryption - At-rest and in-transit encryption
  • ❄️ Access Tiers - Hot, Cool, and Archive tier support
  • ☁️ Azure Native - Full Azure Blob Storage integration
  • 📊 Lifecycle Management - Automatic tier transitions
  • 🗂️ Hierarchical Structure - Organized folder-like storage
  • 🔐 Azure AD Auth - Managed identity and service principal

📦 Installation

# Install SMTP Server and Storage Provider
dotnet add package Zetian
dotnet add package Zetian.Storage.AzureBlob

🚀 Quick Start

Basic Configuration

using Zetian.Server;
using Zetian.Storage.AzureBlob.Extensions;

// Configure with connection string
var server = new SmtpServerBuilder()
    .Port(25)
    .WithAzureBlobStorage("DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey;EndpointSuffix=core.windows.net")
    .Build();

await server.StartAsync();

Advanced Configuration

var server = new SmtpServerBuilder()
    .Port(25)
    .WithAzureBlobStorage(
        "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey;EndpointSuffix=core.windows.net",
        config =>
        {
            config.MaxMessageSizeMB = 100;
            config.EnableSoftDelete = true;
            config.CompressMessageBody = true;
            config.SoftDeleteRetentionDays = 7;
            config.AccessTier = BlobAccessTier.Hot;
            config.ContainerName = "smtp-messages";
            config.StoreMetadataAsBlobProperties = true;
            config.NamingFormat = BlobNamingFormat.DateHierarchy;
        })
    .Build();

Azure AD Authentication

// Using Azure AD Authentication
var server = new SmtpServerBuilder()
    .Port(25)
    .WithAzureBlobStorageAD(
        "mystorageaccount",
        config =>
        {
            config.ContainerName = "email-archive";
            config.AccessTier = BlobAccessTier.Cool;
            config.NamingFormat = BlobNamingFormat.YearMonth;
        })
    .Build();

🛠️ Configuration Options

Option Type Default Description
ConnectionString string - Azure Storage connection string
ContainerName string "smtp-messages" Container name for messages
UseAzureAdAuthentication bool false Use Azure AD authentication
StorageAccountName string - Storage account name (for AD auth)
AutoCreateContainer bool true Auto-create container if needed
NamingFormat enum DateHierarchy Blob naming format
AccessTier enum Hot Default blob access tier
StoreMetadataAsBlobProperties bool true Store metadata as blob properties
EnableSoftDelete bool false Enable soft delete feature
SoftDeleteRetentionDays int 7 Days to retain deleted blobs
MaxMessageSizeMB double 100 Maximum message size in MB
CompressMessageBody bool false Compress message bodies
EnableRetry bool true Enable retry logic
MaxRetryAttempts int 3 Maximum retry attempts
RetryDelayMs int 1000 Delay between retries
ConnectionTimeoutSeconds int 30 Connection timeout
LogErrors bool true Whether to log errors

🎯 Usage Examples

Connection Options

// Connection string with SAS token
.WithAzureBlobStorage(
    "BlobEndpoint=https://myaccount.blob.core.windows.net/;" +
    "SharedAccessSignature=sv=2020-08-04&ss=b&srt=sco&sp=rwdlacx&se=2024-12-31")

// Emulator for local development
.WithAzureBlobStorage("UseDevelopmentStorage=true")

// Azure Government Cloud
.WithAzureBlobStorage(
    "DefaultEndpointsProtocol=https;AccountName=myaccount;" +
    "AccountKey=mykey;EndpointSuffix=core.usgovcloudapi.net")

Blob Naming Strategies

// Flat structure: /msg-123.eml
config.NamingFormat = BlobNamingFormat.Flat;

// Year-Month: /2024-01/msg-123.eml
config.NamingFormat = BlobNamingFormat.YearMonth;

// Domain-based naming
config.NamingFormat = BlobNamingFormat.DomainBased;

// Date hierarchy: /2024/01/15/msg-123.eml
config.NamingFormat = BlobNamingFormat.DateHierarchy;

🔐 Authentication Methods

Azure AD with Managed Identity

// Azure AD authentication (uses DefaultAzureCredential)
.WithAzureBlobStorageAD("mystorageaccount", config =>
{
    config.ContainerName = "smtp-messages";
    config.NamingFormat = BlobNamingFormat.DateHierarchy;
})

// With specific configuration
.WithAzureBlobStorageAD("mystorageaccount", config =>
{
    config.ContainerName = "email-archive";
    config.AccessTier = BlobAccessTier.Cool;
    config.EnableSoftDelete = true;
})

Connection String with Options

.WithAzureBlobStorage(
    "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey",
    config =>
    {
        config.ContainerName = "custom-container";
        config.NamingFormat = BlobNamingFormat.Flat;
    })

🗑️ Soft Delete & Recovery

// Enable soft delete
config.EnableSoftDelete = true;
config.SoftDeleteRetentionDays = 30;

// Recover deleted blob
foreach (var blob in containerClient.GetBlobs(states: BlobStates.Deleted))
{
    var blobClient = containerClient.GetBlobClient(blob.Name);
    await blobClient.UndeleteAsync();
}

🌍 Geo-Redundancy

// Read from secondary region (RA-GRS/RA-GZRS)
config.ConnectionString = 
    "DefaultEndpointsProtocol=https;AccountName=myaccount;" +
    "AccountKey=mykey;EndpointSuffix=core.windows.net;" +
    "BlobEndpoint=https://myaccount-secondary.blob.core.windows.net/";

📈 Monitoring & Analytics

// Enable storage analytics
var serviceProperties = new BlobServiceProperties
{
    Logging = new BlobAnalyticsLogging
    {
        Read = true,
        Write = true,
        Delete = true,
        RetentionPolicy = new BlobRetentionPolicy
        {
            Enabled = true,
            Days = 7
        }
    }
};

await blobServiceClient.SetPropertiesAsync(serviceProperties);

🔒 Security Features

Private Endpoints

// Connect via private endpoint
config.ConnectionString = 
    "DefaultEndpointsProtocol=https;" +
    "AccountName=myaccount;" +
    "AccountKey=mykey;" +
    "BlobEndpoint=https://myaccount.privatelink.blob.core.windows.net/";

🚀 Performance Optimization

Parallel Upload

// Configure parallel upload
var uploadOptions = new BlobUploadOptions
{
    TransferOptions = new StorageTransferOptions
    {
        MaximumConcurrency = 8,
        InitialTransferSize = 256 * 1024,
        MaximumTransferSize = 4 * 1024 * 1024
    }
};

await blobClient.UploadAsync(stream, uploadOptions);

Batch Operations

// Batch delete
var batchClient = blobServiceClient.GetBlobBatchClient();
var batch = batchClient.CreateBatch();

foreach (var blobName in blobsToDelete)
{
    batch.DeleteBlob(containerName, blobName);
}

await batchClient.SubmitBatchAsync(batch);

🔧 Troubleshooting

Common Issues

Authentication Failed

// Check Azure AD permissions
// Verify tenant ID and client credentials
// Storage Blob Data Contributor role required

Archive Tier Access

// Rehydrate before access
if (blobProperties.AccessTier == AccessTier.Archive)
{
    await blobClient.SetAccessTierAsync(AccessTier.Hot);
    // Wait for rehydration (can take hours)
}

📋 Requirements

  • .NET 6.0, 7.0, 8.0, 9.0, or 10.0
  • Zetian SMTP Server package
  • Azure.Storage.Blobs package (included)
  • For managed identity: Azure AD configuration
  • For Data Lake: Hierarchical namespace enabled
  • Azure Storage account (General Purpose v2 recommended)

📚 Documentation & Support

📄 License

MIT License - see LICENSE


Built with ❤️ for the .NET community

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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
1.0.4 926 12/1/2025
1.0.3 145 11/1/2025
1.0.2 210,270 10/29/2025
1.0.1 164 10/25/2025
1.0.0 177 10/25/2025

All changes are detailed at https://zetian.soferity.com/changelog.