How do I use AWS SDK for .NET with Wasabi?
AWS SDK for C# or .NET has been certified for use with Wasabi.
This was tested with AWS SDK version 4.
To use the C#/.NET SDK, execute the following steps.
Make use of Nuget as the package manager as shown in AWS SDK for C# With Wasabi.
Install the AWS SDK for .NET.
Configure and additional AWS CLI profile for Wasabi account using the Wasabi keys (recommended).
See the samples of code below.
In these examples, we have set the profile name as "wasabi" in the "~/.aws/credentials" file.
To help our customers use this SDK with Wasabi, we have provided examples for both IAM and S3.
Replace YourClientInfo/v1.2.3 with your client’s info/version.
Refer to other examples in the AWS documentation Amazon S3 examples using SDK for .NET (v4).
These examples discuss the use of Wasabi's us-east-1 storage region. To use other Wasabi storage regions, use the appropriate Wasabi service URL as described in Service URLs for Wasabi's Storage Regions.
Send all IAM requests to iam.wasabisys.com
Creating a User Using IAM
using System;
using System.Threading.Tasks;
using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
namespace AWSWasabi
{
public static class CreateWasabiUser
{
private static async Task Main()
{
// Wasabi IAM endpoint
var iamConfig = new AmazonIdentityManagementServiceConfig
{
ServiceURL = "https://iam.wasabisys.com"
};
// Resolve credentials from the named profile via the AWS SDK.
// Supports static keys, role_arn/source_profile, SSO, session tokens,
// credential_process, and other supported providers.
var chain = new CredentialProfileStoreChain();
if (!chain.TryGetAWSCredentials("wasabi", out AWSCredentials creds))
{
Console.Error.WriteLine("Could not find AWS profile 'wasabi'");
return;
}
try
{
using var iam = new AmazonIdentityManagementServiceClient(creds, iamConfig);
var createUserRequest = new CreateUserRequest
{
UserName = "c-sharp-user"
};
var resp = await iam.CreateUserAsync(createUserRequest);
Console.WriteLine($"Created user: {resp.User?.UserName} ({resp.User?.Arn})");
}
catch (AmazonIdentityManagementServiceException e)
{
// Surface the actual IAM error from Wasabi
Console.Error.WriteLine($"IAM error: {e.Message}");
}
catch (AmazonClientException e)
{
// SDK/client-side issues (network, config, credential resolution issues, etc.)
Console.Error.WriteLine($"Client error: {e.Message}");
}
catch (Exception e)
{
Console.Error.WriteLine($"Unexpected error: {e}");
}
}
}
}
Creating a Bucket
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using Amazon.S3.Model;
namespace AWSWasabi
{
public static class CreateWasabiBucket
{
private static IAmazonS3 _s3Client = null!;
private const string BucketName = "mt-aws-sdk-test";
private static async Task Main()
{
// 1. Configure the S3-compatible endpoint (Wasabi) using the correct URL for your
// bucket's region and your client's info and version number
var config = new AmazonS3Config
{
ServiceURL = "https://s3.us-east-1.wasabisys.com",
ClientAppId = "YourClientInfo/v1.2.3" // adds: app/YourClientInfo/v1.2.3 to
// the User-Agent header
};
// 2. Load credentials from a named profile (replaces StoredProfileAWSCredentials)
var chain = new CredentialProfileStoreChain();
if (!chain.TryGetAWSCredentials("wasabi", out AWSCredentials awsCredentials))
{
Console.WriteLine("Could not find AWS profile 'wasabi'");
return;
}
// 3. Create S3 client with credentials and config
_s3Client = new AmazonS3Client(awsCredentials, config);
await CreateBucket(_s3Client, BucketName);
}
private static async Task CreateBucket(
IAmazonS3 client,
string bucketName)
{
try
{
var putBucketRequest = new PutBucketRequest
{
BucketName = bucketName
};
await client.PutBucketAsync(putBucketRequest);
Console.WriteLine("Create bucket completed.");
}
catch (AmazonS3Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
}Uploading an Object to the Bucket
Wasabi currently does not support the value STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER for the X-Amz-Content-Sha256 header. As a result, we recommend disabling chunked transfer encoding in applications while uploading the object using the .NET SDK by setting UseChunkEncoding = false until support is available.
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using Amazon.S3.Model;
namespace AWSWasabi
{
public static class UploadWasabiObject
{
private static IAmazonS3 _s3Client = null!;
private const string BucketName = "mt-aws-sdk-test";
private const string ObjectName1 = "test.txt";
// Updated to take any object from the desktop, just adjust the file name above
private static readonly string PathToDesktop =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
private static async Task Main()
{
// 1. Configure the S3-compatible endpoint (Wasabi) using the correct URL for your
// bucket's region and your client's info and version number
var config = new AmazonS3Config
{
ServiceURL = "https://s3.us-east-1.wasabisys.com",
ClientAppId = "YourClientInfo/v1.2.3" // adds: app/YourClientInfo/v1.2.3 to
// the User-Agent header
};
// 2. Load credentials from a named profile (replaces StoredProfileAWSCredentials)
var chain = new CredentialProfileStoreChain();
if (!chain.TryGetAWSCredentials("wasabi", out AWSCredentials awsCredentials))
{
Console.WriteLine("Could not find AWS profile 'wasabi'");
return;
}
// 3. Create S3 client with credentials and config
_s3Client = new AmazonS3Client(awsCredentials, config);
// The method expects the full path, including the file name.
var path = Path.Combine(PathToDesktop, ObjectName1);
await UploadObjectFromFileAsync(_s3Client, BucketName, ObjectName1, path);
}
private static async Task UploadObjectFromFileAsync(
IAmazonS3 client,
string bucketName,
string objectName,
string filePath)
{
try
{
var putRequest = new PutObjectRequest
{
BucketName = bucketName,
Key = objectName,
FilePath = filePath,
UseChunkEncoding = false
};
putRequest.Metadata.Add("x-amz-meta-title", "someTitle");
await client.PutObjectAsync(putRequest);
Console.WriteLine("Upload completed.");
}
catch (AmazonS3Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
}
Reading an Object From the Bucket
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using Amazon.S3.Model;
namespace AWSWasabi
{
public static class DownloadWasabiObject
{
private static IAmazonS3 _s3Client = null!;
private const string BucketName = "mt-aws-sdk-test";
private const string ObjectName1 = "test.txt";
private static async Task Main()
{
// 1. Configure the S3-compatible endpoint (Wasabi) using the correct URL for your
// bucket's region and your client's info and version number
var config = new AmazonS3Config
{
ServiceURL = "https://s3.us-east-1.wasabisys.com",
ClientAppId = "YourClientInfo/v1.2.3" // adds: app/YourClientInfo/v1.2.3 to
// the User-Agent header
};
// 2. Load credentials from a named profile (replaces StoredProfileAWSCredentials)
var chain = new CredentialProfileStoreChain();
if (!chain.TryGetAWSCredentials("wasabi", out AWSCredentials awsCredentials))
{
Console.WriteLine("Could not find AWS profile 'wasabi'");
return;
}
// 3. Create S3 client with credentials and config
_s3Client = new AmazonS3Client(awsCredentials, config);
await GetObject(_s3Client, BucketName, ObjectName1);
}
private static async Task GetObject(
IAmazonS3 client,
string bucketName,
string objectName)
{
try
{
var getRequest = new GetObjectRequest()
{
BucketName = bucketName,
Key = objectName,
};
using var response = await client.GetObjectAsync(getRequest);
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string localPath = Path.Combine(desktop, objectName);
await using var fileStream = File.Create(localPath);
await response.ResponseStream.CopyToAsync(fileStream);
Console.WriteLine($"Downloaded to: {localPath}");
}
catch (AmazonS3Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
}
Deleting the Object From the Bucket
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using Amazon.S3.Model;
namespace AWSWasabi
{
public static class DeleteObjectFromWasabi
{
private static IAmazonS3 _s3Client = null!;
private const string BucketName = "mt-aws-sdk-test";
private const string ObjectName1 = "test.txt";
private static async Task Main()
{
// 1. Configure the S3-compatible endpoint (Wasabi) using the correct URL for your
// bucket's region and your client's info and version number
var config = new AmazonS3Config
{
ServiceURL = "http://s3.us-east-1.wasabisys.com",
ClientAppId = "YourClientInfo/v1.2.3" // adds: app/YourClientInfo/v1.2.3 to
// the User-Agent header
};
// 2. Load credentials from a named profile (replaces StoredProfileAWSCredentials)
var chain = new CredentialProfileStoreChain();
if (!chain.TryGetAWSCredentials("wasabi", out AWSCredentials awsCredentials))
{
Console.WriteLine("Could not find AWS profile 'wasabi'");
return;
}
// 3. Create S3 client with credentials and config
_s3Client = new AmazonS3Client(awsCredentials, config);
await DeleteObject(_s3Client, BucketName, ObjectName1);
}
private static async Task DeleteObject(
IAmazonS3 client,
string bucketName,
string objectName)
{
try
{
var deleteRequest = new DeleteObjectRequest()
{
BucketName = bucketName,
Key = objectName,
};
await client.DeleteObjectAsync(deleteRequest);
Console.WriteLine("Delete object completed.");
}
catch (AmazonS3Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
}