批量DELETE不适用于Azure表存储

时间:2014-05-22 12:17:49

标签: azure azure-storage azure-table-storage

我尝试使用以下代码删除Azure Table Storage上的多个实体。根据Microsoft批量删除操作是allowed for Azure Table Storage。但是,当我尝试执行此代码时,它返回405(不允许方法)错误代码:

// 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);
    }
}

为什么Azure会返回此错误代码,如何避免此错误?

1 个答案:

答案 0 :(得分:2)

这是因为Entity Batch TransactionPOST操作,并且在上面的代码中,您将DELETE作为HTTP方法传递。

enter image description here

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