I try to delete multiply entities on Azure Table Storage using the code below. According to Microsoft bulk delete operations are allowed for Azure Table Storage. However when I try to execute this code, it returns 405 (Method not allowed) error code:
// replace those values
await TableStorage.BatchDelete("TABLENAME", "ACCOUNTNAME", "ACCOUNTKEY", "PARTITIONKEY", new[] {"RowKey1", "RowKey2"});
private static string CreateAuthorizationHeader(string canonicalizedString, string account, string accountKey)
{
string signature;
using (var hmacSha256 = new HMACSHA256(Convert.FromBase64String(accountKey)))
{
var dataToHmac = Encoding.UTF8.GetBytes(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
return String.Format(CultureInfo.InvariantCulture, "SharedKey {0}:{1}", account, signature);
}
public static async Task BatchDelete(string table, string account, string accountKey, string partitionKey, IEnumerable<string> items)
{
var batch = Guid.NewGuid().ToString();
const string storageServiceVersion = "2013-08-15";
var contentType = "multipart/mixed; boundary=batch_" + batch;
var date = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
var token = String.Format("{0}\n{1}\n{2}\n{3}\n{4}", "DELETE", String.Empty, contentType, date, String.Format("/{0}/$batch", account));
var authorizationHeader = CreateAuthorizationHeader(token, account, accountKey);
var builder = new StringBuilder();
builder.AppendLine("--batch_" + batch);
builder.AppendLine("Content-Type: multipart/mixed; boundary=changeset_" + batch);
builder.AppendLine();
foreach (var item in items)
{
var url = String.Format("https://{0}.table.core.windows.net/{1}(PartitionKey='{2}',RowKey='{3}')", account, table, HttpUtility.UrlPathEncode(partitionKey), HttpUtility.UrlPathEncode(item));
builder.AppendLine("--changeset_" + batch);
builder.AppendLine("Content-Type: application/http");
builder.AppendLine("Content-Transfer-Encoding: binary");
builder.AppendLine();
builder.AppendLine("DELETE " + url + " HTTP/1.1");
builder.AppendLine("Content-Type: application/json");
builder.AppendLine("Accept: application/json;odata=nometadata");
builder.AppendLine("Prefer: return-no-content");
builder.AppendLine("DataServiceVersion: 3.0;");
builder.AppendLine("MaxDataServiceVersion: 3.0;NetFx");
builder.AppendLine("If-Match: *");
builder.AppendLine();
builder.AppendLine();
}
builder.AppendLine("--changeset_" + batch + "--");
builder.AppendLine("--batch_" + batch + "--");
var content = Encoding.UTF8.GetBytes(builder.ToString());
using (var client = new WebClient())
{
client.Encoding = Encoding.UTF8;
client.Headers.Add("x-ms-date", date);
client.Headers.Add("x-ms-version", storageServiceVersion);
client.Headers.Add("Authorization", authorizationHeader);
client.Headers.Add("Accept-Charset", "UTF-8");
client.Headers.Add("DataServiceVersion", "3.0");
client.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
client.Headers.Add("Content-Type", contentType);
await client.UploadDataTaskAsync(String.Format("https://{0}.table.core.windows.net/$batch", account), "DELETE", content).ConfigureAwait(false);
}
}
Why do Azure returns this error code and how can I avoid this?