Monday, May 23, 2022

Upload & Download Files in Azure File Storage in .NET CORE WEB API

 Upload Files in Azure File Storage in .NET CORE WEB API

This post is  more about azure  features so will not focus more in coding practices. 

Set up .Net Core 5 Project :

  1. Create a new Project in visual studio 



  1. Select ASP.Net Core Web API and click Next


  1. Enter your project Name "AzureFileStorageTutorial" and click next



  1. Select desired version and create project , here




  1. Create project will be shown like below


Let's go and Setup our file storage in Azure portal first, then again we will come back here

 Setup File Storage in Azure

  1. Open https://portal.azure.com/ and sign in
  2. Click on storage account -> and click on Create button



  1. Select subscription - resource group , enter storage account name e.g. "FileStorageTest" account and leave other field default and click review +create

  1. After step no. 4 storage account will be created , that you can see in the storage account list as below
  2. Click on created storage account name ->Storage Browser(Preview) then  click on add file share  , in right panel enter azuretest in lowercase i.e fileshare name and create


 

  1. Above step will create fileshare which you can find under fileshare list. Here I am going to save files under one directory so will create new directory by click on add directory and named MyFiles


 

After creating directory lest move to our created project in visual studio .Here we need to add some nuget packages as below , in this tutorial I am focusing only upload via fileshare ,so will add only required packages for file shares .

 



After adding above package open appsetting.json, to put all azure related configuration

 


  1. Create AppSettings.cs to read the above config


 

2.. Open startup.cs and put below code , rest setting you can leave as it is.



 

  1. Create class FileDto.cs and property as below


  2. Let's create  services and controller to upload files as below
  1. Create Class Named -FileUploadService and put below code

 

using Microsoft.AspNetCore.Http;

using Microsoft.WindowsAzure.Storage;

using Microsoft.WindowsAzure.Storage.File;

using System;

using System.IO;

using System.Linq;

using System.Threading.Tasks;

 

namespace AzureFileStorageTutorial

{

    public class FileUploadService:IFileUploadService

    {  

        public async Task<int> AzureUpload (FileDto command)

        {

            string fileName;

            byte[] fileInBytes;

            var file = command.File;          

            fileName = Guid.NewGuid() + Path.GetExtension(file.FileName);

            fileInBytes = GetBytes(file);

            if (fileInBytes == null || fileInBytes.Length == 0)

            {

                return 0;

            }

            CloudStorageAccount storageAccount;

            try

            {

                storageAccount = CloudStorageAccount.Parse(AppSettings._settings.AzureFileConnection);

            }

            catch (Exception ex)

            {

                // Log.Error("can't use storage account! " + ex.Message);

                throw ex; // you can handle the way how u want

                // return null;

            }

            CloudFileClient fileClient = storageAccount.CreateCloudFileClient();

            CloudFileShare share = fileClient.GetShareReference(AppSettings._settings.AzureFileShare);

            if ( share.ExistsAsync().Result)

            {

                try

                {

                    CloudFileDirectory rootDir = share.GetRootDirectoryReference();

                    CloudFileDirectory directoryRef;

                    directoryRef = rootDir.GetDirectoryReference(AppSettings._settings.AzureDirectory);

                   await directoryRef.CreateIfNotExistsAsync();

                    CloudFile = directoryRef.GetFileReference(fileName);

                   await cloudFile.UploadFromByteArrayAsync(fileInBytes, 0, fileInBytes.Count());

                    var downloadPath = cloudFile.Uri;

                    //here we can prepareobject to insert in db

                    return 1;

                }

                catch (Exception ex)

                {

                    throw ex;                }

            }

            else

            {              

                throw new BadHttpRequestException("Can't file storage account");

            }

        }

        public byte[] GetBytes(IFormFile formFile)

        {

            using (var memoryStream = new MemoryStream())

            {

                formFile.CopyToAsync(memoryStream);

                return memoryStream.ToArray();

            }

        }

    }

}

  1. Create interface IFileUploadService

 

using System.Threading.Tasks;

namespace AzureFileStorageTutorial

{

    public interface IFileUploadService

    {

        Task<int> AzureUpload(FileDto command);

    }

}

 

  1. Add Controller : FileUploadController and put below code

 

using Microsoft.AspNetCore.Mvc;

namespace AzureFileStorageTutorial.Controllers

{

    public class FileUploadController : Controller

    {

        private readonly IFileUploadService _fileService;

        public FileUploadController(IFileUploadService fileService)

        {

            _fileService = fileService;

        }

        public ActionResult Index()

        {

            return View();

        }

        [HttpPost, DisableRequestSizeLimit]      

        [Route("upload-files")]

        [Consumes("multipart/form-data")]

        public IActionResult UploadFiles(FileDto command)

        {

            var result = _fileService.AzureUpload(command);

            return Ok(result);

        }

    }

}

 

 Don’t foreget to register IFileUploadService in startup .cs

Now run the application and open swagger/ index.html



 

After successfully executed Go to azure portal and open file share ->azuretest->my files

You can see your uploaded file :



DOWNLOAD FILE :

Create below functions in FileUploadService

  public async Task<Stream> DownloadFileStream(string fileName)
        {
            MemoryStream ms = new MemoryStream();
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_appSetting.AzureFileConnection);
            CloudFileClient cloudFileClient = storageAccount.CreateCloudFileClient();
            CloudFileShare cloudFileShare = cloudFileClient.GetShareReference(_appSetting.AzureFileShare);
            if (cloudFileShare.ExistsAsync().Result)
            {
                CloudFileDirectory rootDir = cloudFileShare.GetRootDirectoryReference();
                CloudFileDirectory workarea = rootDir.GetDirectoryReference(_appSetting.AzureDirectory);
                if (workarea.ExistsAsync().Result)
                {
                    CloudFile cloudFile = workarea.GetFileReference(fileName);

                    if (cloudFile.ExistsAsync().Result)
                    {
                        await cloudFile.DownloadToStreamAsync(ms);
                        return cloudFile.OpenReadAsync().Result;
                        // return File(blobStream, cloudFile.Properties.ContentType, file.Name);
                    }
                }
            }
            return null;
        }

Add in IFileUploadService 
 Task<Stream> DownloadFileStream(string fileName);

Add in FileUploadController :
 [HttpGet]
     
        [Route("downloads-file/{fileName}")]
        public IActionResult Download(string fileName)
        {
           
             var stream = _fileService.DownloadFileStream(fileName);
            return File(stream.Result, GetContentType(fileName), fileName);

        }
  private string GetContentType(string path)
        {
            var provider = new FileExtensionContentTypeProvider();
            string contentType;
            if (!provider.TryGetContentType(path, out contentType))
            {
                contentType = "application/octet-stream";
            }
            return contentType;
        }

Open swagger to test download and enter fileName what uploaded in azure file share 


1 comment:

Thanks for your valuable comments

Convert Html to Pdf in azure function and save in blob container

 In this post  I am going to create an azure function ( httpTrigger ) and send html content  which will be converted into PDF and save in bl...