S3 File Operations using .NET 7 WebAPI
Tags: dotnet, dotnetcore, webapi, aws
Published: 2023-03-21 02:11:40


In this chapter, we will create an Asp Net Core Web API on top of .NET 7 that contain 3 APIs. One will upload the file into AWS, another for downloading the file from AWS and another to list the available files. 

Find the complete source code in my GitHub repository below.
> https://github.com/sprabha1990/S3FileOperations.Blazor.NET7

Let's jump into creating a project via Dotnet CLI.

**_Assumption: .NET 7 SDK and runtime installed._**

Running the below commands on the command prompt will create a visual studio solution file, an ASP Net Core Web API project, and an empty Blazor WASM project. 

```
dotnet new sln --name S3FileOperations.NET7 --output S3FileOperations.Blazor.Net7
dotnet new webapi --name S3FileOperations.WebApi --output S3FileOperations.Blazor.Net7/Api
dotnet new blazorwasm-empty --name S3FileOperations.Blazor --output S3FileOperations.Blazor.Net7/WebApp
```

Now running the below commands will add the project files to the solution file. 

```
dotnet sln S3FileOperations.Blazor.Net7\S3FileOperations.NET7.sln add S3FileOperations.Blazor.Net7/Api
dotnet sln S3FileOperations.Blazor.Net7\S3FileOperations.NET7.sln add S3FileOperations.Blazor.Net7/WebApp
```

Let's open the "__S3FileOperations.NET7.sln__" file in the VS2022. You'll find two projects in it. In this chapter, We are going to work on web APIs.

First up, let’s modify the appsettings.json of the Web API project. Make sure that your appsettings.json looks like the one below. Ensure that you are populating the Profile and Region fields with the values you configured earlier in the AWS CLI.

```
  "AWS": {
    "Profile": "default",
    "Region": "us-east-2"
  }
```

Run the following commands via Visual Studio to install the required AWS NuGet packages.

`Install-Package AWSSDK.S3`
`Install-Package AWSSDK.Extensions.NETCore.Setup`

With that done, let’s register the AWS Service into the .NET application’s Container. Open up the Program.cs and make the modifications as below. You might have to use the Amazon.S3 namespace while referencing the below changes.

```
builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions());
builder.Services.AddAWSService<IAmazonS3>();
```

Line 1 Loads the AWS Configuration from the appsettings.json into the application’s runtime.

Line 2 Adds the S3 Service into the pipeline. We will be injecting this interface into our controllers to work with Bucket and Objects!

Its time to create a new API controller under Controllers and name it S3Controller.cs. You would need to inject the IAmazonS3 interface into the constructor of the S3Controller.

![Controller Creation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9z7gwnecx1wmh7tfb8gd.png)

```
    [Route("api/[controller]")]
    [ApiController]
    public class S3Controller : ControllerBase
    {
        private readonly IAmazonS3 _s3Client;

        public S3Controller(IAmazonS3 s3Client)
        {
            _s3Client = s3Client;
        }
    }
```
Let's create an endpoint to upload a file into S3. 

```
 [HttpPost("upload")]
    public async Task<IActionResult> UploadFileAsync(IFormFile file)
    {

    }
```

This API will get the file from the user and upload the file content into S3. 

Before uploading the file, we have to create the bucket in S3. Go to the S3 service in the AWS Management Console and Create a new bucket by pressing the "Create Bucket" button. 

![Press Create Bucket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ubggg6u8pyblvlhcmdth.png)

Provide a name for the bucket and press create bucket at the bottom. 

![Bucket Name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43d58bxou5flgoncgc1o.png)

![Press Create Bucket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ud3vxarlu4e0wphrrzij.png)

Now, you can see your bucket in the bucket list.

![bucket list](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/krky46ktfxd3l2hwee9i.png)

Let's go and implement the API "UploadFileAsync" in the S3Controller class.

```
 [HttpPost("upload")]
        public async Task<IActionResult> UploadFileAsync(IFormFile file)
        {
            var request = new PutObjectRequest()
            {
                BucketName = "blazor-file-transfer-demo",
                Key = file.FileName,
                InputStream = file.OpenReadStream()
            };

            request.Metadata.Add("Content-Type", file.ContentType);
            await _s3Client.PutObjectAsync(request);
            return Ok($"File {file.FileName} uploaded to S3 successfully!");
        }
```
The above API creates a putobjectrequest with bucket name, key, and input stream. The incoming file is converted to a stream via "OpenReadStream()". The bucket name is the one which we created just now and the key name is nothing but the file name.
Calling the PutObjectAsync() API that is available in the S3 client SDK will upload the incoming file data into the S3 bucket we specified.

Now, it's time to create an API for downloading the file. As same as above, create an API called "DownloadFileAsync" inside the S3Controller.

```
        [HttpPost("download")]
        public async Task<IActionResult> DownloadFileAsync(string key)
        {
            var s3Object = await _s3Client.GetObjectAsync("blazor-file-transfer-demo", key);
             return File(s3Object.ResponseStream, s3Object.Headers.ContentType, key);
        }
```

In the above implementation, we are getting the key name (filename) from the user. We will use the key name and the bucket name to fetch the object from the S3 by Calling the GetObjectAsync() API available on the S3 Client SDK. This will provide us with the S3 object as a stream. We will return the stream as a File object to the client application.

At this point, we needed another API to fetch the list of files inside the bucket. 

```
 [HttpGet]
        public async Task<IActionResult> GetAllFilesAsync()
        {
            var request = new ListObjectsV2Request()
            {
                BucketName = "blazor-file-transfer-demo",
            };
            var result = await _s3Client.ListObjectsV2Async(request);
            return Ok(result.S3Objects);
        }
```

That's it! We have created all the required APIs to list all the available files, upload a file and download a file from S3.

We'll see how to upload/download files from the blazor application with the help of these APIs in the next chapter.