0
votes

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?

1

1 Answers

2
votes

It's because Entity Batch Transaction is a POST operation and in your code above you're passing DELETE as HTTP method.

enter image description here

Ref: http://msdn.microsoft.com/en-us/library/azure/dd894038.aspx