Following code is aimed at deleting a row from table with given partition key and rowkey. But I get following request/response in fiddler. How can I correct the error?
Request
DELETE https://hireazurestorageacct.table.core.windows.net/mytable(PartitionKey='sample1',%20RowKey='0001')?timeout=20 HTTP/1.1 Accept: application/json;odata=nometadata x-ms-date: Mon, 08 May 2017 17:59:14 GMT x-ms-version: 2015-04-05 Accept-Charset: UTF-8 MaxDataServiceVersion: 3.0;NetFx DataServiceVersion: 1.0;NetFx If-Match: * Content-Type: application/json Authorization: SharedKeyLite hireazurestorageacct:3ZHX8lYBec+/9ytiNQb+JV5dpFkLAieuwB5veMkLVUU= Host: hireazurestorageacct.table.core.windows.net
Response
HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. Content-Length: 299 Content-Type: application/json Server: Microsoft-HTTPAPI/2.0 x-ms-request-id: a9244f7f-0002-0048-0824-c8afc5000000 Date: Mon, 08 May 2017 17:59:14 GMT
{"odata.error":{"code":"AuthenticationFailed","message":{"lang":"en-US","value":"Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:a9244f7f-0002-0048-0824-c8afc5000000\nTime:2017-05-08T17:59:14.9335100Z"}}}
Code
public static int DeleteEntity(string storageAccount, string accessKey, string tableName, string partitionkey, string rowkey) { string uri = $@"https://{storageAccount}.table.core.windows.net/{tableName}(PartitionKey='{partitionkey}', RowKey='{rowkey}')?timeout=20"; string resource = $@"{tableName}";
// Web request
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "DELETE";
request.Accept = "application/json;odata=nometadata";
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2015-04-05");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
request.Headers.Add("If-Match", "*");
request.ContentType = "application/json";
// Signature string for Shared Key Lite Authentication must be in the form
// StringToSign = Date + "\n" + CanonicalizedResource
// Date
string stringToSign = request.Headers["x-ms-date"] + "\n";
// Canonicalized Resource in the format /{0}/{1} where 0 is name of the account and 1 is resources URI path
stringToSign += "/" + storageAccount + "/" + resource;
// Hash-based Message Authentication Code (HMAC) using SHA256 hash
var hasher = new HMACSHA256(Convert.FromBase64String(accessKey));
// Authorization header
string strAuthorization = "SharedKeyLite " + storageAccount + ":" + Convert.ToBase64String(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)));
// Add the Authorization header to the request
request.Headers.Add("Authorization", strAuthorization);
Thread.Sleep(1000);
// Execute the request
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var r = new StreamReader(response.GetResponseStream()))
{
return (int)response.StatusCode;
}
}
}
catch (WebException ex)
{
// get the message from the exception response
using (var sr = new StreamReader(ex.Response.GetResponseStream()))
{
var res = sr.ReadToEnd();
// Log res if required
}
return (int)ex.Status;
}
}