【问题标题】:Bulk DELETE does not work on Azure Table Storage批量删除不适用于 Azure 表存储
【发布时间】:2014-05-22 12:17:49
【问题描述】:

我尝试使用以下代码删除 Azure 表存储上的多个实体。根据微软的批量删除操作是allowed for Azure Table Storage。但是,当我尝试执行此代码时,它会返回 405 (Method not allowed) 错误代码:

// 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 会返回此错误代码,我该如何避免这种情况?

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢高拉夫!我在令牌字符串和 WebClient 调用中将“DELETE”更改为“POST”。现在可以了!
    猜你喜欢
    • 1970-01-01
    • 2016-06-11
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 2019-03-16
    相关资源
    最近更新 更多