DEV Community

Cover image for Use the .NET Core AWS SDK on Blazor WASM
Victorio Berra
Victorio Berra

Posted on

Use the .NET Core AWS SDK on Blazor WASM

The .NET Core AWS SDK has released an update that allows it to run fully in the browser thanks to WASM.

In this post, id like to show an example that enumerates S3 objects fully client side! You should also be able to utilize services like Cognito and DynamoDB.

Screenshot of Blazor WASM S3 Object Browser

Before we get started, id like to point out some caveats that I ran into while testing this functionality.

⚠ .NET 5 not yet supported! This is because Crypto libraries no longer exist in .NET 5 WASM, so AWS can't sign requests. More info here.
⚠ Today, you must use the UseAlternateUserAgentHeader wherever possible. More on this below.

Lets get started!

Prerequisites

Grab the latest Core 3.1 SDK: https://dotnet.microsoft.com/download/dotnet-core/3.1

AWS (bucket & user)

  1. Create an S3 bucket (or use an existing)
  2. Add a few objects
  3. ❗ Add a CORS policy. Remember, you're in the browser now! The AWS SDK requests to the AWS API will show up right in the networking tab of your browser's dev tools. Very cool!

    [
        {
            "AllowedHeaders": [
                "*"
            ],
            "AllowedMethods": [
                "GET",
                "HEAD"
            ],
            "AllowedOrigins": [
                "*"
            ],
            "ExposeHeaders": [],
            "MaxAgeSeconds": 3000
        }
    ]
    
  4. Create an IAM user and select "Programmatic access", apply an existing policy called AmazonS3ReadOnlyAccess to the user, download the resulting credentials csv or copy the access key ID and secret and store somewhere.

🎉 You are ready to code! 🎊

Code

Create a folder, and inside place a global.json with the following contents:

{
  "sdk": {
    "version": "3.1.403"
  }
}
Enter fullscreen mode Exit fullscreen mode

This tells the dotnet CLI that any dotnet commands you run inside that folder should target 3.1.

Next, scaffold out a new blazor project by running the following commands:

  • dotnet new blazorwasm --name s3blazorwasm
  • cd s3blazorwasm
  • dotnet add package AWSSDK.S3

AWSSDK.S3 has a dependency on AWSSDK.Core.

In _imports.razor import the AWS stuff:

@using Amazon
@using Amazon.S3
@using Amazon.S3.Model
Enter fullscreen mode Exit fullscreen mode

For speed and brevity, open up Counter.razor clear out everything and place the following:

@page "/counter"

<h1>S3 List Objects</h1>

@if (bucketObjectNames == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <ul>
        @foreach (var bucketObjectName in bucketObjectNames)
        {
            <li>@bucketObjectName</li>
        }
    </ul>
}

@code {
    private List<string> bucketObjectNames;

    protected override async Task OnInitializedAsync()
    {
        var config = new AmazonS3Config
        {
            RegionEndpoint = RegionEndpoint.USEast1,
            UseAlternateUserAgentHeader = true
        };

        var s3Client = new AmazonS3Client("YOURKEY", "YOURSECRET", config);

        var bucketObjectResponse = await s3Client.ListObjectsV2Async(new ListObjectsV2Request
        {
            BucketName = "YOURBUCKET"
        });

        bucketObjectNames = bucketObjectResponse.S3Objects.Select(x => x.Key).ToList();
    }
}
Enter fullscreen mode Exit fullscreen mode

ℹ Special note on UseAlternateUserAgentHeader. Internally, the AWS SDK generates a user agent on its own and includes it as part of the signature. When your browser makes a request it ends up using the User-Agent that Chrome generates. This fails the signature check. You need UseAlternateUserAgentHeader to tell AWS to use the generated header (looks like: x-amz-user-agent: aws-sdk-dotnet-netstandard/3.5.7.8 aws-sdk-dotnet-core/3.5.2.0 .NET_Core/(3.2-wasm/1a6e64a9381) OS/web ClientAsync) which gets signed, and sent in the request and validated by AWS properly.

Fire up your app, you should see a list of your objects when you navigate to /counter! Of course feel free to update the page name, route and navigation.

Hopefully this helps you get started, I noticed as this is so new, there are not many docs or information available on any of this yet.

Also, don't forget to delete the user you created and/or remove policies from it, as well as remove the CORS policy from your bucket.

Top comments (0)