我尝试使用以下代码删除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会返回此错误代码,如何避免此错误?
答案 0 :(得分:2)
这是因为Entity Batch Transaction
是POST
操作,并且在上面的代码中,您将DELETE
作为HTTP方法传递。
参考:http://msdn.microsoft.com/en-us/library/azure/dd894038.aspx