AzureStorageWrapper 2.4.2
dotnet add package AzureStorageWrapper --version 2.4.2
NuGet\Install-Package AzureStorageWrapper -Version 2.4.2
<PackageReference Include="AzureStorageWrapper" Version="2.4.2" />
paket add AzureStorageWrapper --version 2.4.2
#r "nuget: AzureStorageWrapper, 2.4.2"
// Install AzureStorageWrapper as a Cake Addin #addin nuget:?package=AzureStorageWrapper&version=2.4.2 // Install AzureStorageWrapper as a Cake Tool #tool nuget:?package=AzureStorageWrapper&version=2.4.2
AzureStorageWrapper
AzureStorageWrapper it's a wrapper for Azure Storage blob service, aimed at simplifying the file upload process and obtaining links for downloading them.
📦 View package on NuGet Gallery 📦 View package on nuget.info
Usage
Dependency injection
To add AzureStorageWrapper to dependencies container, just use the method AddAzureStorageWrapper(...)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAzureStorageWrapper(configuration =>
{
configuration.ConnectionString = "azure-storage-connection-string";
configuration.MaxSasUriExpiration = 600;
configuration.DefaultSasUriExpiration = 300;
configuration.CreateContainerIfNotExists = true;
});
These are the main properties:
- ConnectionString: The connection string of your Azure Storage Account. You can export it by following this documentation
- MaxSasUriExpiration: You can set a maximum duration value for the Shared Access Signature (SAS) of an Azure Storage file to prevent someone from attempting to generate a token with a longer expiration time. The duration is expressed in seconds.
- DefaultSasUriExpiration: You can download a file using AzureStorageWrapper without specifying the
ExpiresIn
property. By doing so, this value will be automatically set. The duration is xpressed in seconds - CreateContainerIfNotExists: When uploading a file to Azure Storage, you need to specify the container, which may not exist and can be created automatically. You can set it to
true
orfalse
based on your requirements. Consider this property if you have automated your infrastructure with an Infrastructure as Code (IaC) mechanism because it affects the state of your infrastructure.
Then you can inject IAzureStorageWrapper
into your services through constructor:
public class MyService
{
private IAzureStorageWrapper _storageWrapper;
public MyService(IAzureStorageWrapper storageWrapper)
{
_storageWrapper = storageWrapper;
}
}
Upload blobs
There are 3 options to upload blobs, all the ways follow the same pattern:
- You need to specify the
Name
andExtension
. - You need to specify the
Container
where you want to store the file. - You can add additional
Metadata
with relevant information.
The file will be placed in Base64
, Bytes
or Stream
property.
Optionally you can specify the UseVirtualFolder
property to save the file in a virtual folder. By default, it is set to true
. We delve deeper into this point later.
Base64
var base64 = "SGVsbG8g8J+Zgg==";
var command = new UploadBase64()
{
Base64 = base64,
Container = "files",
Name = "hello",
Extension = "md",
Metadata = new Dictionary<string, string>() { {"key", "value"} }
};
var response = await _azureStorageWrapper.UploadBlobAsync(command);
Byte []
var bytes = Convert.FromBase64String("SGVsbG8g8J+Zgg==");
var command = new UploadBytes()
{
Bytes = bytes,
Container = "files",
Name = "hello",
Extension = "md",
Metadata = new Dictionary<string, string>() { {"key", "value"} }
};
var response = await _azureStorageWrapper.UploadBlobAsync(command);
Stream
var stream = new MemoryStream(Convert.FromBase64String("SGVsbG8g8J+Zgg=="));
var command = new UploadStream()
{
Stream = stream,
Container = "files",
Name = "hello",
Extension = "md",
Metadata = new Dictionary<string, string>() { {"key", "value"} }
};
var response = await _azureStorageWrapper.UploadBlobAsync(command);
Response after upload blobs
Regardless of the chosen upload mechanism, you will always receive a BlobReference
object after uploading a file.
public class BlobReference
{
public string Container { get; set; }
public string Name { get; set; }
public string Extension { get; set; }
public string Uri { get; set; }
public string SasUri { get; set; }
public DateTime SasExpires { get; set; }
public IDictionary<string, string> Metadata { get; set; }
}
In example, if you upload the file hello.md
file to container files
you will receive a response like:
{
"Container": "files",
"Name": "hello",
"Extension": "md",
"Uri": "https://accountName.blob.core.windows.net/files/5a19306fc5014a4/hello.md",
"SasUri": "https://accountName.blob.core.windows.net/files/5a19306fc5014a4/hello.md?sv=2021-10-04\u0026se=2023-09-03T16%3A17%3A02Z\u0026sr=b\u0026sp=r\u0026sig=8hs8AzxABevSTc5y%2BhOWDDN%2FH5qFSpA8Omj4uqoxzms%3D",
"SasExpires": "2023-09-03T16:17:02.8220993Z",
"Metadata": {
"key": "value",
"_timestamp": "03/09/2023 16:11:02"
}
}
It is your responsibility to save the reference (URI property) of the file you have uploaded to Azure Storage somewhere, as you will need it for later downloads.
Virtual Folders
By default, files are stored in the desired container using virtual folders, allowing you to upload files with the same name without risking name collisions.
For example, a virtual folder with a unique identifier is automatically created between the container name files
and the file name hello.md
, resulting in a URI like this:
https://accountName.blob.core.windows.net/files/5a19306fc5014a4/hello.md
However, you can customize the UseVirtualFolder
property, which by default has a value of true
but you can set it to false
if you wish.
⚠️ When
UseVirtualFolder
is set tofalse
, files will NOT be stored in virtual directories. This change may lead to file name collisions, causing files to be overwritten.
In this scenario, you must implement your own mechanism to generate unique file names.
var base64 = "SGVsbG8g8J+Zgg==";
var command = new UploadBase64()
{
Base64 = base64,
Container = "files",
Name = $"{Guid.NewGuid()}",
Extension = "md",
UseVirtualFolder = false // be careful!
};
var response = await _azureStorageWrapper.UploadBlobAsync(command);
Download blob references
To download a blob reference, you need to specify the Uri
, which you should have stored in your system in some way
var query = new DownloadBlobReference()
{
Uri = "https://accountName.blob.core.windows.net/files/5a19306fc5014a4/hello.md"
ExpiresIn = 60,
};
var response = await _azureStorageWrapper.DownloadBlobReferenceAsync(query);
The response when downloading file reference resembles the response when uploading files:
{
"Container": "files",
"Name": "hello",
"Extension": "md",
"Uri": "https://accountName.blob.core.windows.net/files/5a19306fc5014a4/hello.md",
"SasUri": "https://accountName.blob.core.windows.net/files/5a19306fc5014a4/hello.md?sv=2021-10-04\u0026se=2023-09-03T16%3A17%3A02Z\u0026sr=b\u0026sp=r\u0026sig=8hs8AzxABevSTc5y%2BhOWDDN%2FH5qFSpA8Omj4uqoxzms%3D",
"SasExpires": "2023-09-03T16:17:02.8220993Z",
"Metadata": {
"_timestamp": "03/09/2023 16:11:02"
}
}
Delete blobs
You can delete a blob by specifying the Uri
.
var command = new DeleteBlob()
{
Uri = "https://accountName.blob.core.windows.net/files/5a19306fc5014a4/hello.md"
};
await _azureStorageWrapper.DeleteBlobAsync(command);
Enumerate blobs
You can list all blobs in a container by using the method EnumerateBlobsAsync
.
The response BlobReferenceCollection
will contain a collection of BlobReference
elements.
Without pagination
You should only run this query if you are certain that your container stores a small number of blobs.
var query = new EnumerateBlobs()
{
Container = "files",
Paginate = false
};
var response = await _azureStorageWrapper.EnumerateAllBlobsAsync(query);
With pagination
var query = new EnumerateBlobs()
{
Container = "files",
Paginate = true.
Size = 10,
};
var response = await _azureStorageWrapper.EnumerateBlobsAsync(query);
Then you can request additional pages by using the ContinuationToken
property in the next request.
var firstQuery = new EnumerateBlobs()
{
Container = "files",
Paginate = true,
Size = 10,
};
var firstResponse = await _azureStorageWrapper.EnumerateBlobsAsync(firstQuery);
var secondQuery = new EnumerateBlobs()
{
Container = "files",
Paginate = true,
Size = 10,
ContinuationToken = firstResponse.ContinuationToken
};
var secondResponse = await _azureStorageWrapper.EnumerateBlobsAsync(secondQuery);
Contributors / Collaborators
These individuals have contributed to the repository through suggestions, error corrections, or by opening issues. Thanks 😊
Sponsor
If you like the project, you can consider making a donation at ko-fi.com
Support
You can contact me via Bluesky @sergiobarriel.bsky.social or Twitter @sergiobarriel, or if you have an issue, you can open one 🙂
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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 was computed. 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 was computed. 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. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Azure.Storage.Blobs (>= 12.23.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.2)
-
.NETStandard 2.1
- Azure.Storage.Blobs (>= 12.23.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.2)
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 |
---|---|---|
2.4.2 | 159 | 3/7/2025 |
2.4.1 | 158 | 3/6/2025 |
2.4.0 | 194 | 3/5/2025 |
2.3.1 | 163 | 7/10/2024 |
2.3.0 | 147 | 6/26/2024 |
2.2.15 | 95 | 6/25/2024 |
2.2.14 | 576 | 2/7/2024 |
2.2.13 | 114 | 2/7/2024 |
2.2.12 | 309 | 12/26/2023 |
2.2.11 | 257 | 12/21/2023 |
2.2.10 | 122 | 12/21/2023 |
2.2.8 | 149 | 12/17/2023 |
2.2.7 | 122 | 12/17/2023 |
2.2.6 | 180 | 11/20/2023 |
2.2.5 | 145 | 11/20/2023 |
2.2.4 | 146 | 10/11/2023 |
2.2.3 | 168 | 10/10/2023 |
2.2.2 | 129 | 10/10/2023 |
2.2.1 | 158 | 9/22/2023 |
2.2.0 | 149 | 9/11/2023 |
2.1.2 | 118 | 9/5/2023 |
2.1.1 | 129 | 9/4/2023 |
2.1.0 | 109 | 9/4/2023 |