Sunday, 1 May 2016

ASP.NET Core 1.0–Store Images in Azure Blob When Deployed as Azure Web Site


Data and images are not meant to be stored in Azure Web Site web root directory. It could cause problems doing so, few ideas discussed in below links.
http://stackoverflow.com/questions/12964129/can-i-write-to-file-system-on-azure-web-site
https://social.msdn.microsoft.com/Forums/vstudio/en-US/a8dec55e-c74b-482b-bc65-1c580e4672f4/i-cant-upload-image-on-azure-website?forum=windowsazurewebsitespreview
http://stackoverflow.com/questions/14323548/upload-picture-to-windows-azure-web-site
To store a image or other files in Azure blob container, the below class can be used, with ASP.NET Core 1.0. This class creates the blob container if it does not exist, with required access level (Blob) to allow store and retrieve images to the web site. (Class and interface can be downloaded from here)

Class

using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.AspNet.Http;

namespace BookMyEvents.Services
{
    public class AzureImageHandlerService : IAzureImageHandlerService
    {
        public async Task<string> UploadFileToBlob(IFormFile file, string storageConnectionString, string blobContainerName, string fileName)
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);

            // Create a blob client.
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Get a reference to a container 
            CloudBlobContainer container = blobClient.GetContainerReference(blobContainerName);

            // If container doesn’t exist, create it.
            await container.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, null, null);

            // Get a reference to a blob 
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

            // Create or overwrite the blob with the contents of a local file
            using (var fileStream = file.OpenReadStream())
            {
                await blockBlob.UploadFromStreamAsync(fileStream);
            }

            return blockBlob.Uri.AbsoluteUri;
        }

        public async Task<bool> RemoveFileFromBlob(string storageConnectionString, string blobContainerName, string fileName)
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);

            // Create a blob client.
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Get a reference to a container 
            CloudBlobContainer container = blobClient.GetContainerReference(blobContainerName);

            // If container doesn’t exist, create it.
            await container.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, null, null);

            // Get a reference to a blob 
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

            // Delete the blob if it is existing
            return await blockBlob.DeleteIfExistsAsync();            
        }
    }
}

Interface

using Microsoft.AspNet.Http;
using System.Threading.Tasks;

namespace BookMyEvents.Services
{
    public interface IAzureImageHandlerService
    {
        Task<string> UploadFileToBlob(IFormFile file, string storageConnectionString, string blobContainerName, string fileName);
        Task<bool> RemoveFileFromBlob(string storageConnectionString, string blobContainerName, string fileName);
    }
}

The above class can be used in an ASP.NET Core 1.0 web application as shown below.image
In startup class Startup.cs of ASP.NET Core 1.0 web application, add the class to SerivcesCollection as shown below to make it available for MVC 6.0 controllers.
services.AddScoped<IAzureImageHandlerService, AzureImageHandlerService>();image
Then in a controller, this can be used. MVC 6.0 will auto inject it to controller.image
Upload File usage sampleimage
Remove File usage sampleimage

No comments: