C# Product Image Upload to Amazon S3 / Cloudflare R2
using Amazon.S3;
using Amazon.S3.Model;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/products")]
public class ProductImageController : ControllerBase
{
private readonly IAmazonS3 _s3Client;
private readonly string _bucketName = "your-shop-bucket-name";
// Inject the configured AmazonS3Client via DI
public ProductImageController(IAmazonS3 s3Client)
{
_s3Client = s3Client;
}
[HttpPost("upload")]
[DisableRequestSizeLimit] // Allows Kestrel to accept large files without throwing errors upfront
public async Task UploadProductImage([FromForm] IFormCollection form)
{
if (form.Files.Count == 0 || form.Files.Count > 5)
{
return BadRequest("Please upload between 1 and 5 images.");
}
var uploadedKeys = new List<string>();
foreach (var file in form.Files)
{
if (file.Length == 0) continue;
var fileExtension = Path.GetExtension(file.FileName);
var key = $"products/{Guid.NewGuid()}{fileExtension}";
await using var stream = file.OpenReadStream();
var putRequest = new PutObjectRequest
{
BucketName = _bucketName,
Key = key,
InputStream = stream,
ContentType = file.ContentType,
DisablePayloadSigning = true
};
await _s3Client.PutObjectAsync(putRequest);
uploadedKeys.Add(key);
}
return Ok(new {
message = "Files successfully streamed to R2.",
keys = uploadedKeys
});
}
}
C# Example: Generate Presigned URL for S3 / R2 For to Read The File
using Amazon.S3;
using Amazon.S3.Model;
public string GetPresignedUrl(string fileKey)
{
// 1. Create the request
var request = new GetPreSignedUrlRequest
{
BucketName = "your-shop-bucket-name",
Key = fileKey, // For example: "products/guid-name.jpg"
Expires = DateTime.UtcNow.AddMinutes(15) // The link will expire after 15 minutes
};
// 2. Generate the URL
// This is a purely mathematical operation, no file is downloaded.
string url = _s3Client.GetPreSignedURL(request);
return url;
}