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