Upload File to AWS S3 using .NET Web API
Tags: dotnet, s3, aws, awss3
Published: 2021-09-26 13:21:20

Hello!

I want to bring some "guide" how to use AWS SDK .NET, especially using S3. Simple code that you can follow, please navigate to [here](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/quick-start-s3-1-cross.html), in there you will use .NET console.

## Preparation

* Please install .NET first. You can choose either .NET 5 or .NET Core 3.1.

https://dotnet.microsoft.com/download

(Optional) .NET 6 currently in the RC stage, if you want to try it.

https://dotnet.microsoft.com/download/dotnet/6.0

* Prepare your project. You can use this command. (if you are already have the project, just skip this step)

`dotnet new webapi -o AWSS3Example`

Note: In case you can't find the webapi (when use .NET 6), you can use template from .NET 3.1 since in this article using existing project and the existing project using .NET 3.1 and only change the `TargetFramework` to `.net6.0`.

* Add AWS SDK S3 to your project. You can use this command.

`dotnet add AWSS3Example package AWSSDK.S3`

`dotnet add AWSS3Example package AWSSDK.Extensions.NETCore.Setup`

Note: You can change `AWSS3Example` with your project name.

* Prepare your AWS Environment and S3

I will not bring many steps. You can follow AWS documentation how to setup. As example, you can follow this (the step before setup project): https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/quick-start-s3-1-cross.html

## Coding Time

* I want to write the interface for writing file to S3, so if AWS SDK S3 have major changed, you only change the implementation of the interface. I will write the interface at `AWSS3Example/Services/AWS/IAWSS3Service.cs`.

```csharp
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace AWSS3Example.Services.AWS
{
  public interface IAWSS3Service
  {
    Task<string> UploadFile(IFormFile formFile);
  }
}

```

* Write the implementation. Location `AWSS3Example/Services/AWS/AWSS3Service.cs`.

```csharp
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Amazon.S3;
using Amazon.S3.Model;

namespace AWSS3Example.Services.AWS
{
  public class AWSS3Service : IAWSS3Service
  {
    private IAmazonS3 _s3Client;
    public AWSS3Service(IAmazonS3 amazonS3)
    {
      _s3Client = amazonS3;
    }
    public async Task<string> UploadFile(IFormFile formFile)
    {
      var location = $"uploads/{formFile.FileName}";
      using (var stream = formFile.OpenReadStream())
      {
        var putRequest = new PutObjectRequest
        {
          Key = location,
          BucketName = "upload-test-berv",
          InputStream = stream,
          AutoCloseStream = true,
          ContentType = formFile.ContentType
        };
        var response = await _s3Client.PutObjectAsync(putRequest);
        return location;
      }
    }
  }
}
```

* Write the controller. I write at `AWSS3Example/Controllers/AWSS3Controller.cs`.

```csharp
using System.Threading.Tasks;
using AWSS3Example.Services.AWS;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;

namespace AWSS3Example.Controllers
{
  [ApiController]
  [Route("api/[controller]")]
  public class SThreeController : ControllerBase
  {
    private readonly IAWSS3Service _awsS3Service;
    public SThreeController(IAWSS3Service awsS3Service)
    {
      _awsS3Service = awsS3Service;
    }

    [HttpPost("upload")]
    public async Task<IActionResult> Upload([FromForm] IFormFile file)
    {
      var result = await _awsS3Service.UploadFile(uploadFile.File);
      return Ok(new
      {
        path = result
      });
    }
  }
}

```

* Update the `Startup.cs`

```csharp
using Amazon.S3;
using AWSS3Example.Services.AWS;
// ... the rest of another using
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace AWSS3Example
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // the rest of another register service ...
            services.AddScoped<IAWSS3Service, AWSS3Service>();
            services.AddAWSService<IAmazonS3>();
            // the rest of another register service ...
            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // the rest of your configure, no need to modify this...
        }
    }
}

```

* Run your project.

`dotnet run --project AWSS3Example`

* Test your API

Note: In my case, I use different path, so please use the path that you define at Controller.

![Postman Test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/273mscnv7gtspqkzair3.png)

* Check your S3

![S3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t99m2jd2f34t3zw9zhn7.png)
 

## Repository

You can check here for the repository.

{% github bervproject/NetCoreAPIBoilerplate %}

## Congrats

Congrats. You are finished build API for upload file to AWS S3. Thank you. Hope you enjoy and if have another suggestion, feel free comment in here.

![Unsplash](https://source.unsplash.com/abkEAOjnY0s)

<figcaption>Image source <a href="https://unsplash.com/photos/abkEAOjnY0s">unsplash</a>.</figcaption>