How To Upload , Download And Delete Files From Amazon AWS S3 Cloud Storage Using ASP.NET CORE 3.1

In this blog, we will learn how to upload, download and delete files from amazon AWS S3 Cloud Storage using ASP.NET CORE 3.1.

If you didn’t create an S3 bucket yet, you can check my previous blog. here

I have already created an AWS S3 bucket and logged in to the portal.

Creating application ASP.NET Core Application

Next, we are going to set Project Name “WebStorageDemo” and location.

In the last part, we will choose the .Net Core framework and ASP.NET Core Version 5.0 as the framework for application and few advanced settings for configuring and enabling docker we are not going to enable docker settings for this project.

Now finally click on create button to create a project.

Project structure

The project structure is generated according to the configuration.

After creating the project next, we are going to install the below package from NuGet Packages.

Installing a package from NuGet

1. WindowsAzure.Storage

2. Microsoft.EntityFrameworkCore

3. Microsoft.EntityFrameworkCore.SqlServer

After installing packages next, we have created a table in the database to store document details.

Created Table for Storing Documents

Creating a table with the name DocumentStore for storing document details.

Add Entity and DbContext class along with interface and Concrete for Storing and Reading the document

In this part first, we have added the DocumentStore Entity.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace WebStorageDemo.Models
{
    [Table("DocumentStore")]
    public class DocumentStore
    {
        [Key]
        public int DocumentId { get; set; }
        public string DocumentName { get; set; }
        public string DocumentType { get; set; }
        public DateTime CreatedOn { get; set; }
    }
}

Next, we have added DbContext with the name BlobDbContext.

using Microsoft.EntityFrameworkCore;
using WebStorageDemo.Models;

namespace WebStorageDemo.Repository
{
    public class BlobDbContext : DbContext
    {
        public BlobDbContext(DbContextOptions<BlobDbContext> options) : base(options)
        {
        }
        public DbSet<DocumentStore> DocumentStore { get; set; }
    }
}

After adding BlobDbContext, we are going to add Interface and Concrete in the Repository folder.

using System.Collections.Generic;
using WebStorageDemo.Models;

namespace WebStorageDemo.Repository
{
    public interface IDocumentData
    {
        void Add(DocumentStore documentStore);
        List<DocumentStore> GetDocumentStoresList();
        void Delete(DocumentStore documentStore);
        DocumentStore GetDocumentbyDocumentId(int documentId);
    }
}

AppSettings for Storing AccessKey and SecretKey and configuring database connection string

*NOTE: It is not recommended to store the keys in the appsettings.json file you can use the best methods available for the demo I am storing keys in the appsettings.json file.

After setting keys in the appsettings.json file next, we will configure entity framework core, app settings, and registering the IDocumentData interface.

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IDocumentData, DocumentData>();
    var connection = Configuration.GetConnectionString("DatabaseConnection");
    services.AddDbContext<BlobDbContext>(options => options.UseSqlServer(connection));
    services.Configure<AppSettings>(Configuration.GetSection("AwsSettings"));
    services.AddControllersWithViews();
}

Everything is configured now let’s Create a Controller for Uploading, Downloading, and Deleting Files.

Creating Controller

We will create Controller With the name DemoController with different action methods such as UploadFileDeleteFileDownloadFile, and all files.

Upload File

We will access 2 things in Controller AppSettings, IDocumentData from app settings we will get bucket name, Access key, and Secret key, we will pass the Access key and Secret key to BasicAWSCredentials method and then set RegionEndpoint.

After that, we will get uploaded files details from the IFromFile interface that we will assign to TransferUtilityUploadRequest class of AWS and then finally call TransferUtility class and access UploadAsync method to upload file meanwhile we are going to store all document details to the database.

[HttpGet]
        public IActionResult UploadFile()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            try
            {

                var bucketName = !string.IsNullOrWhiteSpace(_appSettings.FolderName)
                    ? _appSettings.BucketName + @"/" + _appSettings.FolderName
                    : _appSettings.BucketName;

                var credentials = new BasicAWSCredentials(_appSettings.AccessKey, _appSettings.SecretKey);
                var config = new AmazonS3Config
                {
                    RegionEndpoint = Amazon.RegionEndpoint.APSouth1
                };


                using var client = new AmazonS3Client(credentials, config);
                await using var newMemoryStream = new MemoryStream();
                await file.CopyToAsync(newMemoryStream);

                var fileExtension = Path.GetExtension(file.FileName);
                var documentName = $"{GenerateId()}{fileExtension}";

                // URL for Accessing Document for Demo
                var result = $"https://{bucketName}.s3.amazonaws.com/{documentName}";

                var uploadRequest = new TransferUtilityUploadRequest
                {
                    InputStream = newMemoryStream,
                    Key = documentName,
                    BucketName = bucketName,
                    CannedACL = S3CannedACL.PublicRead
                };

                var fileTransferUtility = new TransferUtility(client);
                await fileTransferUtility.UploadAsync(uploadRequest);

                DocumentStore documentStore = new DocumentStore()
                {
                    CreatedOn = DateTime.Now,
                    DocumentId = 0,
                    DocumentName = documentName,
                    DocumentType = file.ContentType
                };

                _documentdata.Add(documentStore);

            }
            catch (AmazonS3Exception amazonS3Exception)
            {
                if (amazonS3Exception.ErrorCode != null
                    && (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") || amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
                {
                    throw new Exception("Check the provided AWS Credentials.");
                }
                else
                {
                    throw new Exception("Error occurred: " + amazonS3Exception.Message);
                }
            }
            return RedirectToAction("AllFiles");
        }

OUTPUT:

We are going to access the Demo/UploadFile path for uploading the file.

After uploading the file, we can see it in the AWS S3 objects section.

While uploading data, we are storing file details in the database.

ALL Files

In this part, we are going to show all files which are stored in the database along with the download and delete feature.

public IActionResult AllFiles()
{
   return View(_documentdata.GetDocumentStoresList());
}

All Files View

@model List<DocumentStore>

<table class="table table-striped">
    <thead>
        <tr>
            <th>DocumentId</th>
            <th>DocumentName</th>
            <th>CreatedOn</th>
            <th>Download</th>
            <th>Delete</th>
        </tr>
    </thead>
    <tbody>

        @foreach (var data in Model)
        {
        <tr>
            <td>@data.DocumentId</td>
            <td>@data.DocumentName</td>
            <td>@data.CreatedOn</td>
            <td>
                <a class="btn btn-success" href="/Demo/DownloadFile/@data.DocumentId">Download</a>
            </td>
            <td>
                <a class="btn btn-danger" href="/Demo/DeleteFile/@data.DocumentId">Delete</a>
            </td>
           
        </tr>
        }
    </tbody>
</table>

Download File

We have created the DownloadFile action method for downloading, which takes the document id as an input parameter and then gets document details. From this document details, we will take the document name and pass it to the GetObjectAsync method, which will get an object from S3 Bucket which contains ResponseStream and object response.Headers.ContentType.

public async Task<IActionResult> DownloadFile(int id)
     {
         try
         {
             var getdocument = _documentdata.GetDocumentbyDocumentId(id);
             var credentials = new BasicAWSCredentials(_appSettings.AccessKey, _appSettings.SecretKey);
             var config = new AmazonS3Config
             {
                 RegionEndpoint = Amazon.RegionEndpoint.APSouth1
             };
             using var client = new AmazonS3Client(credentials, config);
             var fileTransferUtility = new TransferUtility(client);

             var objectResponse = await fileTransferUtility.S3Client.GetObjectAsync(new GetObjectRequest()
             {
                 BucketName = _appSettings.BucketName,
                 Key = getdocument.DocumentName
             });

             if (objectResponse.ResponseStream == null)
             {
                 return NotFound();
             }
             return File(objectResponse.ResponseStream, objectResponse.Headers.ContentType, getdocument.DocumentName);
         }
         catch (AmazonS3Exception amazonS3Exception)
         {
             if (amazonS3Exception.ErrorCode != null
                 && (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") || amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
             {
                 throw new Exception("Check the provided AWS Credentials.");
             }
             else
             {
                 throw new Exception("Error occurred: " + amazonS3Exception.Message);
             }
         }

     }

OUTPUT

Delete file

For Deleting the file, we have created a DeleteFile action method that takes the document id as an input parameter and then documents details. From this document details, we will take the document name and pass it to the DeleteObjectAsync method which will delete an object from S3 Bucket while we are going to call the delete method from DocumentData class to delete the file from the database.

public async Task<IActionResult> DeleteFile(int id)
        {
            try
            {
                var getdocument = _documentdata.GetDocumentbyDocumentId(id);
                _documentdata.Delete(getdocument);

                var credentials = new BasicAWSCredentials(_appSettings.AccessKey, _appSettings.SecretKey);
                var config = new AmazonS3Config
                {
                    RegionEndpoint = Amazon.RegionEndpoint.APSouth1
                };
                using var client = new AmazonS3Client(credentials, config);
                var fileTransferUtility = new TransferUtility(client);
                await fileTransferUtility.S3Client.DeleteObjectAsync(new DeleteObjectRequest()
                {
                    BucketName = _appSettings.BucketName,
                    Key = getdocument.DocumentName
                });

            }
            catch (AmazonS3Exception amazonS3Exception)
            {
                if (amazonS3Exception.ErrorCode != null
                    && (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") || amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
                {
                    throw new Exception("Check the provided AWS Credentials.");
                }
                else
                {
                    throw new Exception("Error occurred: " + amazonS3Exception.Message);
                }
            }
            return RedirectToAction("AllFiles");
        }

OUTPUT:

In this blog, we have learned how to upload, download, and delete files from amazon AWS S3 Cloud Storage using ASP.NET CORE in simple steps.

I hope you guys understand how I can do this. Let me know if you face any difficulties.

You can watch my previous blog here.

Happy Coding {;} 😎

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories