Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So I found some issues with the code:</p> <ul> <li><p>You have chosen to use <strong><code>SharedKeyLite</code></strong> however the format you're using to create the <code>stringToSign</code> in your code is for <strong><code>SharedKey</code></strong>. If you want to use <code>SharedKeyLite</code>, please try to create <code>stringToSign</code> using something like below:</p> <pre><code> stringToSign = String.Format("{0}\n{1}", time, canonicalizedResource); </code></pre></li> </ul> <p>For more details, please see here: <a href="http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx</a></p> <ul> <li><p>I found an issue with the way you're creating <code>StringContent</code>. For some reason, if I use your code, I always get 403 error. Try this instead:</p> <pre><code> var stringContent = new StringContent(body); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/atom+xml"); HttpResponseMessage messageResult = await request.PostAsync(uri, stringContent); </code></pre></li> </ul> <p>Try this code instead. It makes use of SharedKey:</p> <pre><code>using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net.Http; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace SOPostToAzureTable { static class Utilities { internal static string Account = "account name"; internal static string Key = "account key"; } class Program { static void Main(string[] args) { var task = Task.Factory.StartNew(() =&gt; InsertEntityAsync("SOTest")); Task[] tasks = new Task[1]; tasks[0] = task; Task.WaitAll(tasks); Console.WriteLine("Press any key to continue"); Console.ReadLine(); } public static async Task&lt;string&gt; InsertEntityAsync(string tableName) { string uri = @"https://" + Utilities.Account + ".table.core.windows.net/" + tableName; return await UploadEntityAsync(tableName, uri); } public static async Task&lt;string&gt; UploadEntityAsync(string urlPath, string uri) { string body = @"&lt;?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?&gt; &lt;entry xmlns:d=""http://schemas.microsoft.com/ado/2007/08/dataservices"" xmlns:m=""http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"" xmlns=""http://www.w3.org/2005/Atom""&gt; &lt;title /&gt; &lt;updated&gt;2013-08-30T21:03:45.4991966Z&lt;/updated&gt; &lt;author&gt; &lt;name /&gt; &lt;/author&gt; &lt;id /&gt; &lt;content type=""application/xml""&gt; &lt;m:properties&gt; &lt;d:PartitionKey&gt;SOTest&lt;/d:PartitionKey&gt; &lt;d:RowKey&gt;{0}&lt;/d:RowKey&gt; &lt;d:A m:type=""Edm.String""&gt;A&lt;/d:A&gt;&lt;d:B m:type=""Edm.String""&gt;B&lt;/d:B&gt; &lt;/m:properties&gt; &lt;/content&gt; &lt;/entry&gt;"; body = string.Format(body, Guid.NewGuid()); HttpClient request = new HttpClient(); string formatedTime = DateTime.UtcNow.ToString("R"); request.DefaultRequestHeaders.Add("x-ms-date", formatedTime); //Adding the Authorization header to the request string authorization = GetSignedString("POST", formatedTime, urlPath, Utilities.Account, Utilities.Key); request.DefaultRequestHeaders.Add("Authorization", authorization); request.DefaultRequestHeaders.TryAddWithoutValidation("Content-Length", body.Length.ToString()); var stringContent = new StringContent(body); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/atom+xml"); HttpResponseMessage messageResult = await request.PostAsync(uri, stringContent); return messageResult.ToString(); } public static string GetSignedString(string httpMethod, string time, string urlPath, string account, string key) { String contentMD5 = String.Empty; String contentType = "application/atom+xml"; String canonicalizedResource = String.Format("/{0}/{1}", account, urlPath); //stringToSign format for SharedKey String stringToSign = String.Format( "{0}\n{1}\n{2}\n{3}\n{4}", httpMethod, contentMD5, contentType, time, canonicalizedResource); //stringToSign format for SharedKeyLite //stringToSign = String.Format("{0}\n{1}", time, canonicalizedResource); string signedKey = SignThis(stringToSign, key, account); return signedKey; } private static String SignThis(String canonicalizedString, string Key, string Account) { String signature = string.Empty; byte[] unicodeKey = Convert.FromBase64String(Key); using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey)) { Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString); signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac)); } String authorizationHeader = String.Format( CultureInfo.InvariantCulture, "{0} {1}:{2}", "SharedKey", Account, signature); return authorizationHeader; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload