[英]delete azure table storage row without checking for existence
我多年来一直在使用 azure 表存储,但我不确定使用最新的 WindowsAzure.Storage 库版本 5.0.1-preview 执行此操作的“正确”方法是什么(用于新的 ASP.NET 5 应用):
问题:给定一个分区键和行键,删除该行而不先检查是否存在,如果不存在则不会失败。
当前解决方案:此代码有效...但异常处理令人困惑:
public async Task DeleteRowAsync(CloudTable table, string partition, string row)
{
var entity = new DynamicTableEntity(partition, row);
entity.ETag = "*";
var op = TableOperation.Delete(entity);
try
{
await table.ExecuteAsync(op);
}
catch (Exception ex)
{
var result = RequestResult.TranslateFromExceptionMessage(ex.Message);
if (result == null || result.HttpStatusCode != 404)
throw ex;
}
}
问题:
异常本身将我指向这个 TranslateFromExceptionMessage 方法......我找不到关于它和 WrappedStorageException (抛出的异常的类型)的大量信息。 这是检查存储异常中的 404 错误的某种新的/首选方法吗? 有谁知道现在是否所有存储异常都会使用它,或者我是否需要编写代码来测试和弄清楚?
有一个 StorageException 类型的 InnerException。 大概我们使用 StorageException.RequestInformation.HttpStatusCode 的旧代码可以以相同的方式访问这个内部异常。 那是“OK”,还是以某种方式更好或更健壮地解析这些新的 XML 错误消息?
对于这种情况,我应该考虑完全不同的方法吗?
当配置为使用 Azure 表存储时,在 AspNet WebHooks 项目中可以找到类似的方法。 查看Microsoft.Aspnet.WebHooks.custom.AzureStorage
StorageManager类。
我不确定这会在您已经发现的基础上增加多少,但它们处理所有内容而不会引发异常并始终返回状态代码,以便您可以根据需要做出反应。
这里的一个区别是它们将table
和operation
传递给多用途的 ExecuteAsync 方法,而不是专门用于删除的方法,但这只是一个实现细节。
他们示例中的相关代码:
public async Task<TableResult> ExecuteAsync(CloudTable table, TableOperation operation)
{
if (table == null)
{
throw new ArgumentNullException(nameof(table));
}
if (operation == null)
{
throw new ArgumentNullException(nameof(operation));
}
try
{
var result = await table.ExecuteAsync(operation);
return result;
}
catch (Exception ex)
{
var errorMessage = GetStorageErrorMessage(ex);
var statusCode = GetStorageStatusCode(ex);
var message = string.Format(CultureInfo.CurrentCulture, AzureStorageResources.StorageManager_OperationFailed, statusCode, errorMessage);
_logger.Error(message, ex);
return new TableResult { HttpStatusCode = statusCode };
}
}
public string GetStorageErrorMessage(Exception ex)
{
if (ex is StorageException storageException && storageException.RequestInformation != null)
{
var status = storageException.RequestInformation.HttpStatusMessage != null ?
storageException.RequestInformation.HttpStatusMessage + " " :
string.Empty;
var errorCode = storageException.RequestInformation.ExtendedErrorInformation != null ?
"(" + storageException.RequestInformation.ExtendedErrorInformation.ErrorMessage + ")" :
string.Empty;
return status + errorCode;
}
else if (ex != null)
{
return ex.Message;
}
return string.Empty;
}
public int GetStorageStatusCode(Exception ex)
{
return ex is StorageException se && se.RequestInformation != null ? se.RequestInformation.HttpStatusCode : 500;
}
RequestResult.TranslateFromExceptionMessage
方法现在被标记为[Obsolete]
,我想要一种自己忽略 404 的方法。
根据您查看RequestInformation.HttpStatusCode
提示,我想出了以下内容:
try
{
await table.ExecuteAsync(op);
}
catch (StorageException storEx)
{
if (storEx.RequestInformation.HttpStatusCode != 404)
{
throw;
}
}
如果您使用的是最新的客户端 ( Azure.Data.Tables ),则删除方法会自动吞下 404 响应并且不会抛出。 这种方法避免了编写引入竞争条件的代码(在执行操作之前首先检查)或必须使用 try/catch 块处理这种情况的需要。
如果您想知道该操作是实际删除了一个表还是它不存在,您可以检查响应的 Status 属性。
Response response = await tableClient.DeleteAsync();
if (response.Status == (int)HttpStatusCode.NotFound)
{
// entity didn't exist)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.