Amazon SimpleDB Basics in C# - PutAttribute

In response to a question in the comments on how to do a PutAttribute on SimpleDB, I’ve put together this post. These are fragments of code and not a complete source file. Hopefully if someone is looking for information, this can help as a guide. This code was written for Windows Phone 7 (i.e. Silverlight). To implement this fully, you’ll need to fill in the methods named CalculateStringToSignV2 and HmacSign. It is done via a GET method so all of the data is sent in the query string. Some of the code is a derivation from existing samples.

[sourcecode language=“csharp”] public void UpdateData(string itemName, AwsCredentials credentials) {

 IDictionary<string, string> parameters = new Dictionary<string, string>();
 parameters["Action"] = "PutAttributes";
 parameters["DomainName"] = DomainName;
 parameters["ItemName"] = itemName;

 // in my sample, I have a column called "LastUpdated" that I want to update with the current time.
 parameters["Attribute.1.Name"] = "LastUpdated";
 parameters["Attribute.1.Value"] = DateTime.Now.ToUniversalTime().ToString(CultureInfo.InvariantCulture);
 parameters["Attribute.1.Replace"] = true.ToString();

 AddRequiredParameters(parameters, GetMethod, credentials);

 var queryString = GetParametersAsString(parameters);

 var uri = new Uri(string.Format("{0}?{1}", SimpleDbUrl, queryString));
 var updateRequest = WebRequest.Create(uri) as HttpWebRequest;
 if (updateRequest != null)
        {
            updateRequest.Method = GetMethod;
            AsyncDataPackage asyncDataPackage = new AsyncDataPackage() { PostData = queryString, Request = updateRequest, Credentials = credentials};
            updateRequest.BeginGetResponse(UpdateResponseHandler, asyncDataPackage);

        }

}

private void AddRequiredParameters(IDictionary<string, string> parameters, string accessMethod, AwsCredentials credentials) { if (String.IsNullOrEmpty(credentials.AccessKey)) { throw new ArgumentNullException("The AWS Access Key cannot be NULL or empty"); } if (parameters.ContainsKey("Signature")) { parameters.Remove("Signature"); } parameters["SignatureVersion"] = signatureVersion; parameters["SignatureMethod"] = signatureMethod; parameters["Timestamp"] = GetFormattedTimestampIso8601(0); parameters["Version"] = serviceVersion;

        string toSign = CalculateStringToSignV2(parameters, SimpleDbUrl, credentials.AccessKey, accessMethod);
        string auth;
        auth = HmacSign(toSign, credentials.SecretKey);

        parameters[&quot;AWSAccessKeyId&quot;] = credentials.AccessKey;
        parameters[&quot;Signature&quot;] = auth;

    }

private static string GetParametersAsString(IDictionary<string, string> parameters) { StringBuilder data = new StringBuilder(512); foreach (string key in (IEnumerable<string>)parameters.Keys) { string value = parameters[key]; if (value != null) { data.Append(key); data.Append(‘=’); data.Append(UrlEncode(value)); data.Append(’&’); } } string result = data.ToString(); return result.Remove(result.Length - 1); }

public class AwsCredentials
{
    public string AccessKey { get; set; }
    public string SecretKey { get; set; }
}

public class AsyncDataPackage { public HttpWebRequest Request { get; set; } public string PostData { get; set; } public AwsCredentials Credentials { get; set; } } [/sourcecode]