diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs index e0b70dc66c..ec854b7be3 100644 --- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs +++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs @@ -18,39 +18,49 @@ namespace Volo.Abp.BlobStoring.Azure public override async Task SaveAsync(BlobProviderSaveArgs args) { var blobName = AzureBlobNameCalculator.Calculate(args); - var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName); + var configuration = args.Configuration.GetAzureConfiguration(); - if (!args.OverrideExisting && await BlobExistsAsync(blobClient)) + if (!args.OverrideExisting && await BlobExistsAsync(configuration, blobName)) { throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{args.ContainerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten."); } - await blobClient.UploadAsync(args.BlobStream, true); + if (configuration.CreateContainerIfNotExists) + { + await CreateContainerIfNotExists(args.Configuration.GetAzureConfiguration()); + } + + await GetBlobClient(configuration, blobName).UploadAsync(args.BlobStream, true); } public override async Task DeleteAsync(BlobProviderDeleteArgs args) { var blobName = AzureBlobNameCalculator.Calculate(args); - var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName); - return await blobClient.DeleteIfExistsAsync(); + + if (await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName)) + { + return await GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName).DeleteIfExistsAsync(); + } + + return false; } public override async Task ExistsAsync(BlobProviderExistsArgs args) { var blobName = AzureBlobNameCalculator.Calculate(args); - var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName); - return await BlobExistsAsync(blobClient); + return await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName); } public override async Task GetOrNullAsync(BlobProviderGetArgs args) { var blobName = AzureBlobNameCalculator.Calculate(args); - var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName); - if (!await BlobExistsAsync(blobClient)) + + if (!await BlobExistsAsync(args.Configuration.GetAzureConfiguration(), blobName)) { return null; } + var blobClient = GetBlobClient(args.Configuration.GetAzureConfiguration(), blobName); var download = await blobClient.DownloadAsync(); var memoryStream = new MemoryStream(); await download.Value.Content.CopyToAsync(memoryStream); @@ -69,9 +79,22 @@ namespace Volo.Abp.BlobStoring.Azure return blobServiceClient.GetBlobContainerClient(configuration.ContainerName); } - private static async Task BlobExistsAsync(BlobBaseClient blobClient) + protected virtual async Task CreateContainerIfNotExists(AzureBlobProviderConfiguration configuration) + { + var blobContainerClient = GetBlobContainerClient(configuration); + await blobContainerClient.CreateIfNotExistsAsync(); + } + + private async Task BlobExistsAsync(AzureBlobProviderConfiguration configuration, string blobName) + { + // Make sure Blob Container exists. + return await ContainerExistsAsync(GetBlobContainerClient(configuration)) && + (await GetBlobClient(configuration, blobName).ExistsAsync()).Value; + } + + private static async Task ContainerExistsAsync(BlobContainerClient blobContainerClient) { - return (await blobClient.ExistsAsync()).Value; + return (await blobContainerClient.ExistsAsync()).Value; } } } diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs index 67f6eca307..a0906ed31f 100644 --- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs +++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfiguration.cs @@ -14,6 +14,15 @@ set => _containerConfiguration.SetConfiguration(AzureBlobProviderConfigurationNames.ContainerName, Check.NotNullOrWhiteSpace(value, nameof(value))); } + /// + /// Default value: false. + /// + public bool CreateContainerIfNotExists + { + get => _containerConfiguration.GetConfigurationOrDefault(AzureBlobProviderConfigurationNames.CreateContainerIfNotExists, false); + set => _containerConfiguration.SetConfiguration(AzureBlobProviderConfigurationNames.CreateContainerIfNotExists, value); + } + private readonly BlobContainerConfiguration _containerConfiguration; public AzureBlobProviderConfiguration(BlobContainerConfiguration containerConfiguration) diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs index f90f037046..b8fbff19d2 100644 --- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs +++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProviderConfigurationNames.cs @@ -4,5 +4,6 @@ { public const string ConnectionString = "Azure.ConnectionString"; public const string ContainerName = "Azure.ContainerName"; + public const string CreateContainerIfNotExists = "Azure.CreateContainerIfNotExists"; } } diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs index a45d209b32..5e66be4e19 100644 --- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs +++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo/Abp/BlobStoring/Azure/AbpBlobStoringAzureTestModule.cs @@ -38,12 +38,8 @@ namespace Volo.Abp.BlobStoring.Azure })); var configuration = context.Services.GetConfiguration(); - _connectionString = configuration["Azure:ConnectionString"]; - var blobServiceClient = new BlobServiceClient(_connectionString); - blobServiceClient.CreateBlobContainer(_randomContainerName); - Configure(options => { options.Containers.ConfigureAll((containerName, containerConfiguration) => @@ -52,6 +48,7 @@ namespace Volo.Abp.BlobStoring.Azure { azure.ConnectionString = _connectionString; azure.ContainerName = _randomContainerName; + azure.CreateContainerIfNotExists = true; }); }); }); @@ -60,7 +57,7 @@ namespace Volo.Abp.BlobStoring.Azure public override void OnApplicationShutdown(ApplicationShutdownContext context) { var blobServiceClient = new BlobServiceClient(_connectionString); - blobServiceClient.DeleteBlobContainer(_randomContainerName); + blobServiceClient.GetBlobContainerClient(_randomContainerName).DeleteIfExists(); } }