As at March 2018, the latest version of the AWS SDK for .NET Core has changed. It now uses asynchronous programming. Many of the method signatures have changed. While you still cannot change metadata without the object copy solution that Dan has suggested, the code to do so has.
My solution is to update the existing S3 object with the modified metadata.
The following works for me to update a single metadata value (based on key and new value). I've got two loops for setting the metadata but it could be optimised to just have one:
string fileContents = string.Empty;
Dictionary<string, string> fileMetaData = null;
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = setKeyName
};
var response = await s3Client.GetObjectAsync(request);
// Read the contents of the file
using (var stream = response.ResponseStream)
{
// Get file contents
TextReader tr = new StreamReader(stream);
fileContents = tr.ReadToEnd();
}
// Create the File Metadata collection
fileMetaData = new Dictionary<string, string>();
foreach (string metadataKey in response.Metadata.Keys)
{
fileMetaData.Add(metadataKey, response.Metadata[metadataKey]);
}
// Update the metadata value (key to update, new value)
fileMetaData[metaDataKeyToUpdate] = metaDataNewValue;
// Update the existing S3 object
PutObjectRequest putRequest1 = new PutObjectRequest
{
BucketName = bucketName,
Key = setKeyName,
ContentBody = fileContents
};
// Set the metadata
foreach (string metadataKey in response.Metadata.Keys)
{
putRequest1.Metadata.Add(metadataKey, fileMetaData[metadataKey]);
}
PutObjectResponse response1 = await s3Client.PutObjectAsync(putRequest1);