AWSSDK.S3 (for AWS S3 Service)
Tags: aws, cloud, dotnet, csharp
Published: 2021-08-24 10:09:14

Let's start s series of articles about `AWS SDKs` available for `.Net` developers to use in their applications.

First of all, let's ask a simple question...
#➽What is the AWS SDK for .NET?
☞The AWS SDK for .NET makes it easier to build .NET applications that tap into cost-effective, scalable, and reliable AWS services such as Amazon Simple Storage Service (`Amazon S3`) and Amazon Elastic Compute Cloud (`Amazon EC2`). The SDK simplifies the use of AWS services by providing a set of libraries that are consistent and familiar for .NET developers.

![AWS SDKs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0gezp1dj5xdijne3b6n6.png)

Let's start in this article with the first SDK which is `AWSSDK.S3` ...

`AWSSDK.S3` is a SDK that helps .Net Developers to use Access Amazon Simple Storage Service (`Amazon S3`) in their applications  to create buckets and store objects.

`Amazon S3` is storage for the Internet. It is designed to make web-scale computing easier.

`Amazon S3` has a simple web services interface that you can use to store and retrieve any amount of data, at any time, from anywhere on the web. It gives any developer access to the same highly scalable, reliable, fast, and inexpensive data storage infrastructure that Amazon uses to run its own global network of web sites, to read more about it [go here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html).
_________________________________________________________________
Before starting, Here is the Github Repo for the code we are going to write today, clone it and use it if you want to test the SDK
{% github Ahmed-Adel3/AWSSDK.S3-Demo %}
_________________________________________________________________
#➽Installing AWSSDK.S3 :
☞`AWSSDK.S3` is installed mainly from Nuget, which is a package management system for the .NET platform. With NuGet, you can install the AWSSDK packages, as well as several other extensions, to your project, and here is [Nuget Website] (https://www.nuget.org/)

There is 3 ways to install `AWSSDK.S3` (or any other Nuget Package in General)

✎ __1- Using NuGet from the Command prompt or terminal:__
➤ Go to the [AWSSDK packages on NuGet](https://www.nuget.org/profiles/awsdotnet)
 and determine which packages you need in your project; today we will install , [AWSSDK.S3](https://www.nuget.org/packages/AWSSDK.S3/).
➤ Copy the .NET CLI command from that package's webpage, as shown in the following example.

```csharp
dotnet add package AWSSDK.S3 --version 3.3.110.19
```

➤ In your project's directory, run that .NET CLI command. NuGet also installs any dependencies, such as __AWSSDK.Core__ (which is the main dependency for all AWS SDKs for .Net ).

✎ __2- Using NuGet Package Manager in Visual Studio:__
➤ In Solution Explorer, right-click your project, and then choose Manage NuGet Packages from the context menu.

➤ In the left pane of the NuGet Package Manager, choose Browse. You can then use the search box to search for the package you want to install.

➤ The following figure shows installation of the `AWSSDK.S3` package.

![Nuget Package Manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n4lkyb66z16pt22piytz.png)

✎ __3- Using NuGet from the Package Manager Console:__
➤ In Visual Studio, choose Tools, NuGet Package Manager, Package Manager Console.

➤ You can install the AWSSDK packages you want from the Package Manager Console by using the Install-Package command. For example, to install AWSSDK.S3, use the following command.
```csharp
PM> Install-Package AWSSDK.S3
```
➤ If you need to install an earlier version of a package, use the -Version option and specify the package version you want, as shown in the following example.
```csharp
PM> Install-Package AWSSDK.S3 -Version 3.3.106.6
```
_________________________________________________________________
#➽So, How can we use it ?
☞ Let's assume that we have a `.Net Core 3.1` application:

__1- Get AWS Access keys:__
➤ the first step you need to do is to get your access key ID and secret access key and here is the steps to do that ..

__a)__ Use your AWS account ID or account alias, your IAM user name, and your password to sign in to the IAM console.
https://console.aws.amazon.com/iam

__b)__ In the navigation bar on the upper right, choose your user name, and then choose My Security Credentials.

![My Security Credentials](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/usctm0q1m2heq6v3cl3o.png)

__c)__ Expand the Access keys (access key ID and secret access key) section.

__d)__ Choose Create New Access Key then copy the key to paste it somewhere else for safekeeping, choose Show Access Key. To save the access key ID and secret access key to a .csv file to a secure location on your computer, choose Download Key File.

__Now we have our access key ID and secret access key, let's continue ...__

__2- let's start coding:__
➤ First let's assume that we have a class called "MyS3Service" registered in our app to handle connection to S3 Buckets.

```csharp
using System;
using Amazon;
using Amazon.S3;
using Amazon.S3.Util;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using System.Threading.Tasks;

public class MyS3Service
{
    private readonly IAmazonS3 s3Client;
    public MyS3Service()
    {
        s3Client = new AmazonS3Client(
             "Your Aws Access Key Id here",
             "Your Aws Secret Access Key here",
             RegionEndpoint.GetBySystemName("Your Region Name here"));
    }
}
```

> **Note:** I included all the namespaces needed for the upcoming APIs...

➤ Fill your keys and your region name in `AmazonS3Client` constructor (Note that: this constructor has many other overloads to connect to your account)

✅ that's it , you are now connected to your AWS account...
_________________________________________________________________
#➽Let's now check what we can do with this SDK ...

☞__1- Creating S3 Bucket:__
• Let's add a function to our previously created class MyS3Service

```csharp 
public async Task CreateNewBucketAsync()
{
    try
    {
        // to check if there is another bucket with the same name
        // make sure to use V2 of the function because V1 is obsolete
        if (!(await AmazonS3Util.DoesS3BucketExistV2Async(s3Client, "Your New Bucket Name Here")))
        {
            var putBucketRequest = new PutBucketRequest
            {
                BucketName = "Your New Bucket Name Here",
                UseClientRegion = true
            };
            PutBucketResponse putBucketResponse = await s3Client.PutBucketAsync(putBucketRequest);
        }
    }
    catch (AmazonS3Exception e)
    {
        Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
    }
    catch (Exception e)
    {
        Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
    }
}
```
>Note that the following rules apply for naming buckets in Amazon S3:

>• Bucket names must be between 3 and 63 characters long.

>• Bucket names can consist only of lowercase letters, numbers, dots (.), and hyphens (-).

>• Bucket names must begin and end with a letter or number.

>• Bucket names must not be formatted as an IP address (for example, 192.168.5.4).

>• Bucket names must not start with the prefix xn--.

>• Bucket names must not end with the suffix -s3alias. This suffix is reserved for access point alias names

☞__2- Upload an Object in the bucket:__

```csharp
public async Task UploadObjectAsync()
{
    try
    {
        // Method 1. Put object-specify only key name for the new object.
        var putRequest1 = new PutObjectRequest
        {
            BucketName = "Your Bucket Name Here",
            Key = "Unique identifier for the object",
            ContentBody = "sample text"
        };

        PutObjectResponse response1 = await s3Client.PutObjectAsync(putRequest1);

        //______________________________________________________________________

        //Method  2. Put the object-set ContentType and add metadata.
        var putRequest2 = new PutObjectRequest
        {
            BucketName = "Your Bucket Name Here",
            Key = "Unique identifier for the object",
            FilePath = "File path goes here",
            ContentType = "text/plain"
        };

        putRequest2.Metadata.Add("x-amz-meta-title", "someTitle");
        PutObjectResponse response2 = await s3Client.PutObjectAsync(putRequest2);
    }
    catch (AmazonS3Exception e)
    {
        Console.WriteLine(
                "Error encountered ***. Message:'{0}' when writing an object"
                , e.Message);
    }
    catch (Exception e)
    {
        Console.WriteLine(
            "Unknown encountered on server. Message:'{0}' when writing an object"
            , e.Message);
    }
}
```

☞__3- Upload a file:__
```csharp
public async Task UploadFileAsync()
{
    try
    {
        var yourBucketName = "TestBucket";
        var yourFilepath = "Your File path";
        var yourfileKey = "Your Unique Key here";

        var fileTransferUtility =new TransferUtility(s3Client);

        // Option 1. Upload a file. The file name is used as the object key name.
        await fileTransferUtility.UploadAsync(yourFilepath, yourBucketName);
        Console.WriteLine("Upload 1 completed");

        //______________________________________________________________________

        // Option 2. Specify object key name explicitly.
        await fileTransferUtility.UploadAsync(yourFilepath, yourBucketName, yourfileKey);
        Console.WriteLine("Upload 2 completed");

        //______________________________________________________________________
        
        // Option 3. Upload data from a type of System.IO.Stream.
        using (var fileToUpload =new FileStream(yourFilepath, FileMode.Open, FileAccess.Read))
        {
            await fileTransferUtility.UploadAsync(fileToUpload, yourBucketName, yourfileKey);
        }
        Console.WriteLine("Upload 3 completed");

        //______________________________________________________________________
        // Option 4. Specify advanced settings.
        var fileTransferUtilityRequest = new TransferUtilityUploadRequest
        {
            BucketName = yourBucketName,
            FilePath = yourFilepath,
            StorageClass = S3StorageClass.StandardInfrequentAccess,
            PartSize = 6291456, // 6 MB.
            Key = yourfileKey,
            CannedACL = S3CannedACL.PublicRead // to determine Access control list to file
        };

        //if you need to add metadata to your files
        fileTransferUtilityRequest.Metadata.Add("param1", "Value1");
        fileTransferUtilityRequest.Metadata.Add("param2", "Value2");

        await fileTransferUtility.UploadAsync(fileTransferUtilityRequest);
        Console.WriteLine("Upload 4 completed");
    }
    catch (AmazonS3Exception e)
    {
        Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
    }
    catch (Exception e)
    {
        Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
    }
}
```

☞__4- Get Object data:__
```csharp
public async Task ReadObjectDataAsync()
{
    var yourBucketName = "TestBucket";
    var yourfileKey = "Your Unique Key here";
    string responseBody = "";
    try
    {
        GetObjectRequest request = new GetObjectRequest
        {
            BucketName = yourBucketName,
            Key = yourfileKey
        };
        using (GetObjectResponse response = await s3Client.GetObjectAsync(request))
        using (Stream responseStream = response.ResponseStream)
        using (StreamReader reader = new StreamReader(responseStream))
        {
            string title = response.Metadata["x-amz-meta-title"]; // Assume you have "title" as medata added to the object.
            string contentType = response.Headers["Content-Type"];
            Console.WriteLine("Object metadata, Title: {0}", title);
            Console.WriteLine("Content type: {0}", contentType);
            responseBody = reader.ReadToEnd(); // Now you process the response body.
        }
    }
    catch (AmazonS3Exception e)
    {
        // If bucket or object does not exist
        Console.WriteLine("Error encountered ***. Message:'{0}' when reading object", e.Message);
    }
    catch (Exception e)
    {
        Console.WriteLine("Unknown encountered on server. Message:'{0}' when reading object", e.Message);
    }
}
```
☞__5- Delete Object:__
```csharp
public async Task DeleteObject()
{
    try
    {
        var yourBucketName = "TestBucket";
        var yourfileKey = "Your Unique Key here";
        var deleteObjectRequest = new DeleteObjectRequest
        {
            BucketName = yourBucketName,
            Key = yourfileKey
        };

        Console.WriteLine("Deleting an object");
        await s3Client.DeleteObjectAsync(deleteObjectRequest);
    }
    catch (AmazonS3Exception e)
    {
        Console.WriteLine("Error encountered on server. Message:'{0}' when deleting an object", e.Message);
    }
    catch (Exception e)
    {
        Console.WriteLine("Unknown encountered on server. Message:'{0}' when deleting an object", e.Message);
    }
}
```
☞__6- List all objects in a bucket:__
```csharp
public async Task GetObjectsList()
{
    try
    {
        ListVersionsRequest request = new ListVersionsRequest()
        {
            BucketName = "Your Bucket Name",
            // You can optionally specify key name prefix in the request
            // if you want list of object versions of a specific object.

            // For this example we limit response to return list of 2 versions.
            MaxKeys = 2
        };
        do
        {
            ListVersionsResponse response = await s3Client.ListVersionsAsync(request);
            // Process response.
            foreach (S3ObjectVersion entry in response.Versions)
            {
                Console.WriteLine("key = {0} size = {1}",entry.Key, entry.Size);
            }

            // If response is truncated, set the marker to get the next 
            // set of keys.
            if (response.IsTruncated)
            {
                request.KeyMarker = response.NextKeyMarker;
                request.VersionIdMarker = response.NextVersionIdMarker;
            }
            else
            {
                request = null;
            }
        } while (request != null);
    }
    catch (AmazonS3Exception e)
    {
        Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
    }
    catch (Exception e)
    {
        Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
    }
}
```
________________________________________________
That's is for now :)
Please wait for other topics about AWS other SDKs ..

Please have a look at the repo of this topic 
{% github Ahmed-Adel3/AWSSDK.S3-Demo %}
__➽To use this repo :__
☞You just to put your ows __AWS Access Key__ and __AWS Secret Access Key__ in the main method in the console app and try.