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
<PackageReference Include="Zetian.Storage.AzureBlob" Version="1.0.4" />
<PackageVersion Include="Zetian.Storage.AzureBlob" Version="1.0.4" />
<PackageReference Include="Zetian.Storage.AzureBlob" />
paket add Zetian.Storage.AzureBlob --version 1.0.4
#r "nuget: Zetian.Storage.AzureBlob, 1.0.4"
#:package Zetian.Storage.AzureBlob@1.0.4
#addin nuget:?package=Zetian.Storage.AzureBlob&version=1.0.4
#tool nuget:?package=Zetian.Storage.AzureBlob&version=1.0.4
Zetian.Storage.AzureBlob - Azure Cloud Storage
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
- Issues: GitHub Issues
- Examples: GitHub Examples
- Discussions: GitHub Discussions
- Documentation: Zetian Documentation
- Azure Docs: Azure Blob Storage Documentation
📄 License
MIT License - see LICENSE
Built with ❤️ for the .NET community
| Product | Versions 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. |
-
net10.0
- Azure.Identity (>= 1.18.0-beta.2)
- Azure.Storage.Blobs (>= 12.27.0-beta.1)
- Zetian.Storage (>= 1.0.6)
-
net6.0
- Azure.Identity (>= 1.18.0-beta.2)
- Azure.Storage.Blobs (>= 12.27.0-beta.1)
- Zetian.Storage (>= 1.0.6)
-
net7.0
- Azure.Identity (>= 1.18.0-beta.2)
- Azure.Storage.Blobs (>= 12.27.0-beta.1)
- Zetian.Storage (>= 1.0.6)
-
net8.0
- Azure.Identity (>= 1.18.0-beta.2)
- Azure.Storage.Blobs (>= 12.27.0-beta.1)
- Zetian.Storage (>= 1.0.6)
-
net9.0
- Azure.Identity (>= 1.18.0-beta.2)
- Azure.Storage.Blobs (>= 12.27.0-beta.1)
- Zetian.Storage (>= 1.0.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
All changes are detailed at https://zetian.soferity.com/changelog.