aws-sdk-net
You must generate an Access Key before getting started. All examples will utilize access_key_id and access_key_secret variables which represent the Access Key ID and Secret Access Key values you generated.
This example uses version 3 of the aws-sdk-net ↗ package. You must pass in the R2 configuration credentials when instantiating your S3 service client:
In this example, you will pass credentials explicitly to the IAmazonS3 initialization. If you wish, use a shared AWS credentials file or the SDK store in-line with other AWS SDKs. Refer to Configure AWS credentials ↗ for more details.
private static IAmazonS3 s3Client;
public static void Main(string[] args){ // Retrieve your S3 API credentials for your R2 bucket via API tokens (see: https://developers.cloudflare.com/r2/api/tokens) var accessKey = "<ACCESS_KEY_ID>"; var secretKey = "<SECRET_ACCESS_KEY>"; var credentials = new BasicAWSCredentials(accessKey, secretKey); s3Client = new AmazonS3Client(credentials, new AmazonS3Config { // Provide your Cloudflare account ID ServiceURL = "https://<ACCOUNT_ID>.r2.cloudflarestorage.com", });}The ListBucketsAsync ↗ and ListObjectsAsync ↗ methods can be used to list buckets under your account and the contents of those buckets respectively.
static async Task ListBuckets(){ var response = await s3Client.ListBucketsAsync();
foreach (var s3Bucket in response.Buckets) { Console.WriteLine("{0}", s3Bucket.BucketName); }}sdk-examplemy-bucketstatic async Task ListObjectsV2(){ var request = new ListObjectsV2Request { BucketName = "my-bucket" };
var response = await s3Client.ListObjectsV2Async(request);
foreach (var s3Object in response.S3Objects) { Console.WriteLine("{0}", s3Object.Key); }}dog.pngcat.pngThe PutObjectAsync ↗ and GetObjectAsync ↗ methods can be used to upload objects and download objects from an R2 bucket respectively.
static async Task PutObject(){ var request = new PutObjectRequest { FilePath = @"/path/file.txt", BucketName = "my-bucket", DisablePayloadSigning = true, DisableDefaultChecksumValidation = true };
var response = await s3Client.PutObjectAsync(request);
Console.WriteLine("ETag: {0}", response.ETag);}ETag: "186a71ee365d9686c3b98b6976e1f196"static async Task GetObject(){ var bucket = "my-bucket"; var key = "file.txt";
var response = await s3Client.GetObjectAsync(bucket, key);
Console.WriteLine("ETag: {0}", response.ETag);}ETag: "186a71ee365d9686c3b98b6976e1f196"The GetPreSignedURL ↗ method allows you to sign ahead of time, giving temporary access to a specific operation. In this case, presigning a PutObject request for sdk-example/file.txt.
static string? GeneratePresignedUrl(){ AWSConfigsS3.UseSignatureVersion4 = true; var presign = new GetPreSignedUrlRequest { BucketName = "my-bucket", Key = "file.txt", Verb = HttpVerb.GET, Expires = DateTime.Now.AddDays(7), };
var presignedUrl = s3Client.GetPreSignedURL(presign);
Console.WriteLine(presignedUrl);
return presignedUrl;}https://<ACCOUNT_ID>.r2.cloudflarestorage.com/my-bucket/file.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<credential>&X-Amz-Date=<timestamp>&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=<signature>Was this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark
-