Uploading (’Putting’) binary files to Amazon S3 in C#
So I’ve had a technology crush on S3 since it came out but I’ve only recently started to explore it. After downloading the C# S3 SOAP sample code, the first thing I tried to do was upload a jpeg. The upload was pretty easy, but upon trying to access the file via the s3 url, I only received an unintelligible string sequence. Opening it in a hex editor proved that the file didn’t get uploaded as a byte sequence, but as one long string. The reason, it turns out, was that I was using the wrong api call (duh), the call that accepts a string parameter:
public PutObjectResult put(string bucket, string key, string obj, MetadataEntry[] metadata, Grant[] accessControlList)
{
DateTime timestamp = AWSDateFormatter.GetCurrentTimeResolvedToMillis();
string signature = makeSignature(”PutObjectInline”, timestamp);
ASCIIEncoding ae = new ASCIIEncoding();
return s3.PutObjectInline(bucket, key, metadata, ae.GetBytes( obj ), obj.Length, accessControlList, StorageClass.STANDARD, false, awsAccessKeyId, timestamp, true, signature, null);
}
To use this call, I had to convert my byte sequence into a string, which was then converted to another byte sequence using an ascii encoding. That process corrupts your original byte sequence because not all bytes fit into the ascii spectrum. But where was the correct method signature? It turns out it was omitted, at least in version dated 2006-10-13. Adding the following method to AwsConnection.cs fixed my upload woes:
public PutObjectResult put(string bucket, string key, byte[] objBytes, MetadataEntry[] metadata, Grant[] accessControlList)
{
DateTime timestamp = AWSDateFormatter.GetCurrentTimeResolvedToMillis();
string signature = makeSignature(”PutObjectInline”, timestamp);
return s3.PutObjectInline(bucket, key, metadata, objBytes, objBytes.Length, accessControlList, StorageClass.STANDARD, false, awsAccessKeyId, timestamp, true, signature, null);
}
