Problem
How to use Azure Blob storage in ASP.NET Core.
Solution
Create a class library and add NuGet package - WindowsAzure.Storage
Add a class to encapsulate settings,
- public class AzureBlobSetings
- {
- public AzureBlobSetings(string storageAccount,
- string storageKey,
- string containerName)
- {
- if (string.IsNullOrEmpty(storageAccount))
- throw new ArgumentNullException("StorageAccount");
-
- if (string.IsNullOrEmpty(storageKey))
- throw new ArgumentNullException("StorageKey");
-
- if (string.IsNullOrEmpty(containerName))
- throw new ArgumentNullException("ContainerName");
-
- this.StorageAccount = storageAccount;
- this.StorageKey = storageKey;
- this.ContainerName = containerName;
- }
-
- public string StorageAccount { get; }
- public string StorageKey { get; }
- public string ContainerName { get; }
- }
Add a class to encapsulate a blob item,
- public class AzureBlobItem
- {
- public AzureBlobItem(IListBlobItem item)
- {
- this.Item = item;
- }
-
- public IListBlobItem Item { get; }
-
- public bool IsBlockBlob => Item.GetType() == typeof(CloudBlockBlob);
- public bool IsPageBlob => Item.GetType() == typeof(CloudPageBlob);
- public bool IsDirectory => Item.GetType() == typeof(CloudBlobDirectory);
-
- public string BlobName => IsBlockBlob ? ((CloudBlockBlob)Item).Name :
- IsPageBlob ? ((CloudPageBlob)Item).Name :
- IsDirectory ? ((CloudBlobDirectory)Item).Prefix :
- "";
-
- public string Folder => BlobName.Contains("/") ?
- BlobName.Substring(0, BlobName.LastIndexOf("/")) : "";
-
- public string Name => BlobName.Contains("/") ?
- BlobName.Substring(BlobName.LastIndexOf("/") + 1) : BlobName;
- }
Add a class to encapsulate storage access. Add a private helper methods to access storage,
- private async Task<CloudBlobContainer> GetContainerAsync()
- {
-
- CloudStorageAccount storageAccount = new CloudStorageAccount(
- new StorageCredentials(settings.StorageAccount, settings.StorageKey), false);
-
-
- CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
-
-
- CloudBlobContainer blobContainer =
- blobClient.GetContainerReference(settings.ContainerName);
- await blobContainer.CreateIfNotExistsAsync();
-
- return blobContainer;
- }
-
- private async Task<CloudBlockBlob> GetBlockBlobAsync(string blobName)
- {
-
- CloudBlobContainer blobContainer = await GetContainerAsync();
-
-
- CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference(blobName);
-
- return blockBlob;
- }
-
- private async Task<List<AzureBlobItem>> GetBlobListAsync(
- bool useFlatListing = true)
- {
-
- CloudBlobContainer blobContainer = await GetContainerAsync();
-
-
- var list = new List<AzureBlobItem>();
- BlobContinuationToken token = null;
- do
- {
- BlobResultSegment resultSegment =
- await blobContainer.ListBlobsSegmentedAsync("", useFlatListing,
- new BlobListingDetails(), null, token, null, null);
- token = resultSegment.ContinuationToken;
-
- foreach (IListBlobItem item in resultSegment.Results)
- {
- list.Add(new AzureBlobItem(item));
- }
- } while (token != null);
-
- return list.OrderBy(i => i.Folder).ThenBy(i => i.Name).ToList();
- }
Now add public methods to upload and download blob items,
- public async Task UploadAsync(string blobName, string filePath)
- {
-
- CloudBlockBlob blockBlob = await GetBlockBlobAsync(blobName);
-
-
- using (var fileStream = System.IO.File.Open(filePath, FileMode.Open))
- {
- fileStream.Position = 0;
- await blockBlob.UploadFromStreamAsync(fileStream);
- }
- }
-
- public async Task UploadAsync(string blobName, Stream stream)
- {
-
- CloudBlockBlob blockBlob = await GetBlockBlobAsync(blobName);
-
-
- stream.Position = 0;
- await blockBlob.UploadFromStreamAsync(stream);
- }
-
- public async Task<MemoryStream> DownloadAsync(string blobName)
- {
-
- CloudBlockBlob blockBlob = await GetBlockBlobAsync(blobName);
-
-
- using (var stream = new MemoryStream())
- {
- await blockBlob.DownloadToStreamAsync(stream);
- return stream;
- }
- }
-
- public async Task DownloadAsync(string blobName, string path)
- {
-
- CloudBlockBlob blockBlob = await GetBlockBlobAsync(blobName);
-
-
- await blockBlob.DownloadToFileAsync(path, FileMode.Create);
- }
Add methods to get a list of blob items,
- public async Task<List<AzureBlobItem>> ListAsync()
- {
- return await GetBlobListAsync();
- }
-
- public async Task<List<string>> ListFoldersAsync()
- {
- var list = await GetBlobListAsync();
- return list.Where(i => !string.IsNullOrEmpty(i.Folder))
- .Select(i => i.Folder)
- .Distinct()
- .OrderBy(i => i)
- .ToList();
- }
Inject and use storage helper,
- public class HomeController : Controller
- {
- private readonly IAzureBlobStorage blobStorage;
-
- public HomeController(IAzureBlobStorage blobStorage)
- {
- this.blobStorage = blobStorage;
- }
Note
Sample code has a controller with actions for listing, downloading and uploading items.
In ASP.NET Core Web Application, configure services,
- public void ConfigureServices(
- IServiceCollection services)
- {
- services.AddScoped<IAzureBlobStorage>(factory =>
- {
- return new AzureBlobStorage(new AzureBlobSetings(
- storageAccount: Configuration["Blob_StorageAccount"],
- storageKey: Configuration["Blob_StorageKey"],
- containerName: Configuration["Blob_ContainerName"]));
- });
-
- services.AddMvc();
- }
Discussion
The sample code will require you to set up an Azure account, blob storage account, and container. Instructions for these can be found here.
Source Code
GitHub