Skip to content

Commit aefd9d4

Browse files
authored
Azure Blog Storage: Support for nested containers to upload files (#391)
* Split containerName to get root and sub containers * Update azure storage docs to point nested containers
1 parent f128449 commit aefd9d4

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

docs/Media/Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The following settings in `appsettings.json` control media upload functionality:
2424
| AuthenticationMode | string | Authentication method - either `Default` for Microsoft Entra ID or `ConnectionString` for connection string auth |
2525
| ConnectionString | string | Azure Storage connection string (only used and mandatory when AuthenticationMode is `ConnectionString`) |
2626
| ServiceUrl | string | Azure Blob Storage service URL (only used and mandatory when AuthenticationMode is `Default`) |
27-
| ContainerName | string | Name of the Azure Storage container to store uploaded files. |
27+
| ContainerName | string | Name of the Azure Storage container to store uploaded files. It can be nested containers as well ``path/to/upload`` |
2828
| CdnEndpoint | string | Optional CDN endpoint to use for uploaded images. If set, the blog will return this URL instead of the storage account URL for uploaded assets. |
2929

3030
## Authentication Methods

src/LinkDotNet.Blog.Web/Features/Services/FileUpload/AzureBlobStorageService.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
using System;
2-
using System.IO;
3-
using System.Threading.Tasks;
41
using Azure.Identity;
52
using Azure.Storage.Blobs;
63
using Azure.Storage.Blobs.Models;
74
using Microsoft.Extensions.Options;
5+
using System;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Threading.Tasks;
89

910
namespace LinkDotNet.Blog.Web.Features.Services.FileUpload;
1011

@@ -23,8 +24,10 @@ public async Task<string> UploadFileAsync(string fileName, Stream fileStream, Up
2324

2425
var containerName = azureBlobStorageConfiguration.Value.ContainerName;
2526
var client = CreateClient(azureBlobStorageConfiguration.Value);
26-
var blobContainerClient = client.GetBlobContainerClient(containerName);
27-
var blobClient = blobContainerClient.GetBlobClient(fileName);
27+
28+
var (rootContainer, subContainer) = SplitContainerName(containerName);
29+
var blobContainerClient = client.GetBlobContainerClient(rootContainer);
30+
var blobClient = blobContainerClient.GetBlobClient($"{subContainer}/{fileName}");
2831

2932
var blobOptions = new BlobUploadOptions();
3033
if (options.SetCacheControlHeader)
@@ -39,6 +42,18 @@ public async Task<string> UploadFileAsync(string fileName, Stream fileStream, Up
3942
return GetAssetUrl(blobClient.Uri.ToString(), azureBlobStorageConfiguration.Value);
4043
}
4144

45+
private static (string rootContainer, string subContainer) SplitContainerName(string containerName)
46+
{
47+
var containerNames = containerName.Split('/', StringSplitOptions.RemoveEmptyEntries);
48+
49+
if (containerNames.Length == 0)
50+
return (string.Empty, string.Empty);
51+
52+
var rootContainer = containerNames[0];
53+
var subContainer = string.Join("/", containerNames.Skip(1));
54+
return (rootContainer, subContainer);
55+
}
56+
4257
private static BlobServiceClient CreateClient(UploadConfiguration configuration)
4358
{
4459
if (configuration.AuthenticationMode == AuthenticationMode.ConnectionString.Key)

0 commit comments

Comments
 (0)