In this article we will explore AWS S3 and see how we can upload files to our S3 buckets from an .NET 6 Web API.
You can watch the full video on YouTube with detail explanation of S3
You can find the link to the source code below
https://github.com/mohamadlawand087/NET6-S3
Now lets get started
The first thing we need to do is to create our application inside our terminal
dotnet new webapi -n AutoUpload
Create the classlib which is responsible for S3 communication
dotnet new classlib -n AwsS3
Add reference between the webapi and the classlib
dotnet add AutoUpload/AutoUpload.csproj reference AwsS3/AwsS3.csproj
Now we open the solution in VsCode and we delete the auto generated class inside AwsS3
and we add 2 new folders
- Models
- Services
We install S3 nuget package inside the AwsS3 class lib
dotnet add package AWSSDK.S3
Now inside our Models folder we need to create our S3 Model, let us add a class called S3Object
public class S3Object { public string Name { get; set; } = null!; public MemoryStream InputStream { get; set; } = null!; public string BucketName { get; set; } = null!; }
Now we need to add another class which will represent the data which is being sent back from S3 after the upload, so we will need to create a new class called S3ResponseDto
public class S3ResponseDto { public int StatusCode { get; set; } public string Message { get; set; } }
Now we need to another class which will be responsible for storing the AWS credentials which we will utilise to communicate with S3 bucket, so we will create a new class called AwsCredentials a
public class AwsCredentials { public string AccessKey { get; set; } = ""; public string SecretKey { get; set; } = ""; }
Now we need to add a section so we can get all of the required configuration so inside our AwsS3 classlib we will create a new folder called configurations in the root directory and inside that folder we will create a new class called Constants which represent the config values name
public class Constants { public static string AccessKey = "AccessKey"; public static string SecretKey = "SecretKey"; }
Now inside our service folder we will add a new interface call IStorageService
using AwsS3.Models; using AwsS3.Models.DTO; namespace AwsS3.Services; public interface IStorageService { Task<S3ResponseDto> UploadFileAsync(S3Object obj, AwsCredentials awsCredentialsValues); }
Now we need to create the service, so we create a new class called StorageService inside the Services folder
using AwsS3.Models; using AwsS3.Models.DTO; using Amazon.S3; using Amazon.S3.Transfer; using AwsS3.Configurations; using Amazon.Runtime; namespace AwsS3.Services; public class StorageService : IStorageService { //private readonly IConfigurationManager _config; public StorageService(IConfigurationManager config) { //_config = config; } public async Task<S3ResponseDto> UploadFileAsync(S3Object obj, AwsCredentials awsCredentialsValues) { //var awsCredentialsValues = _config.ReadS3Credentials(); Console.WriteLine($"Key: {awsCredentialsValues.AccessKey}, Secret: {awsCredentialsValues.SecretKey}"); var credentials = new BasicAWSCredentials(awsCredentialsValues.AccessKey, awsCredentialsValues.SecretKey); var config = new AmazonS3Config() { RegionEndpoint = Amazon.RegionEndpoint.EUWest2 }; var response = new S3ResponseDto(); try { var uploadRequest = new TransferUtilityUploadRequest() { InputStream = obj.InputStream, Key = obj.Name, BucketName = obj.BucketName, CannedACL = S3CannedACL.NoACL }; // initialise client using var client = new AmazonS3Client(credentials, config); // initialise the transfer/upload tools var transferUtility = new TransferUtility(client); // initiate the file upload await transferUtility.UploadAsync(uploadRequest); response.StatusCode = 201; response.Message = $"{obj.Name} has been uploaded sucessfully"; } catch(AmazonS3Exception s3Ex) { response.StatusCode = (int)s3Ex.StatusCode; response.Message = s3Ex.Message; } catch(Exception ex) { response.StatusCode = 500; response.Message = ex.Message; } return response; } }
Now we need to go to our API and update our appsettings.json
"AwsConfiguration": { "AWSAccessKey": "ACCESSKEYID", "AWSSecretKey": "SECRETKEY" }
Next we need to update our controller
using AwsS3.Models; using AwsS3.Services; using Microsoft.AspNetCore.Mvc; namespace AutoUpload.Controllers; [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private readonly IStorageService _storageService; private readonly IConfiguration _config; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController( ILogger<WeatherForecastController> logger, IConfiguration config, IStorageService storageService) { _logger = logger; _config = config; _storageService = storageService; } [HttpPost(Name = "UploadFile")] public async Task<IActionResult> UploadFile(IFormFile file) { // Process file await using var memoryStream = new MemoryStream(); await file.CopyToAsync(memoryStream); var fileExt = Path.GetExtension(file.FileName); var docName = $"{Guid.NewGuid}.{fileExt}"; // call server var s3Obj = new S3Object() { BucketName = "live-demo-bucket821", InputStream = memoryStream, Name = docName }; var cred = new AwsCredentials() { AccessKey = _config["AwsConfiguration:AWSAccessKey"], SecretKey = _config["AwsConfiguration:AWSSecretKey"] }; var result = await _storageService.UploadFileAsync(s3Obj, cred); // return Ok(result); } }
Please comment your questions below
Top comments (1)
git hub code is 404 not found