The shortest ever S3 C#/SOAP/WCF client

Just the code

Download the sample project from:

AmazonS3SoapWcfSample.zip, 30KB, 8/4/2009

The sample is self-contained. You don’t need to follow any of the text in this post to build and use it. If trying to replicate the sample’s behavior in a different program, take a look at step 2 below regarding adding the Amazon S3 service reference

The shortest ever S3 C#/SOAP/WCF client

I put this together as an answer to a question on stackoverflow. What’s the simplest, most straight-forward way to access the Amazon S3 service from a C# program? To me, the obstacle has always been with authenticating the requests. You have to dig it out of Amazon’s sample code set up in the days before WCF. So here’s the shortest I could get it to:

  1. Step 1: Start Visual Studio 2008, create a new C# Windows console application.

  2. Step 2: Add the S3 WSDL as a service reference. In Solution Explorer, right click References, select Add Service Reference. Type in the S3 WSDL address in the Address box: http://s3.amazonaws.com/doc/2006-03-01/AmazonS3.wsdl. Click Go. “AmazonS3” should show in the Services box. Enter a namespace. I entered Amazon.S3. Click OK.

  3. Step 3: Modify Program.cs to look something like the following:

using System;
using System.Globalization;
using System.Text;
using System.Security.Cryptography;
using AmazonS3SoapWcfSample.Amazon.S3;

namespace AmazonS3SoapWcfSample {
	class Program {
		private const string accessKeyId     = "YOURACCESSKEYIDHERE0";
		private const string secretAccessKey = "YOURSECRETACCESSKEYHEREANDYESITSTHATLONG";

		public static DateTime LocalNow() {
			DateTime now = DateTime.Now;
			return new DateTime(
				now.Year, now.Month, now.Day,
				now.Hour, now.Minute, now.Second,
				now.Millisecond, DateTimeKind.Local);
		}

		public static string SignRequest(string secret, string operation, DateTime timestamp) {
			HMACSHA1 hmac         = new HMACSHA1(Encoding.UTF8.GetBytes(secret));
			string   isoTimeStamp = timestamp.ToUniversalTime().ToString(
				"yyyy-MM-ddTHH:mm:ss.fffZ",
				CultureInfo.InvariantCulture);
			string   signMe       = "AmazonS3" + operation + isoTimeStamp;
			string   signature    = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(signMe)));
			return signature;
		}

		static void Main(string[] args) {
			DateTime       now    = LocalNow();
			AmazonS3Client client = new AmazonS3Client();

			var result = client.ListAllMyBuckets(
				accessKeyId,
				now,
				SignRequest(secretAccessKey, "ListAllMyBuckets", now));

			foreach (var bucket in result.Buckets) {
				Console.WriteLine(bucket.Name);
			}
		}
	}
}

If you now insert your access key ID and secret access key in the appropriate spots and run the program, you should get a listing of your S3 buckets. The AmazonS3Client class has all the SOAP operations available as instance methods on it.

Works for you? Have an idea how to make it even shorter? –leave a comment.