删除azure表存储行而不检查是否存在



我已经使用azure表存储多年了,我不确定用最新的WindowsAzure做这件事的"正确"方法是什么。存储库,版本5.0.1-预览版(用于新的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;
    }
}

问题:

  1. 异常本身指向我这个TranslateFromExceptionMessage方法…我找不到关于它和WrappedStorageException(抛出的异常类型)的大量信息。这是一种新的/首选的方式来检查存储异常的404错误吗?有人知道是否所有的存储异常现在将使用这个,或者我需要写代码来测试和弄清楚吗?

  2. 有一个类型为StorageException的InnerException。假设使用StorageException.RequestInformation.HttpStatusCode的旧代码可以以相同的方式访问这个内部异常。这样可以吗?或者解析这些新的XML错误消息是否更好或更健壮?

  3. 对于这种情况,我是否应该考虑另一种方法?

如果您使用的是最新的客户端(Azure.Data.Tables),则delete方法会自动吞下404响应而不会抛出。这种方法避免了编写引入竞争条件的代码(在执行操作之前先检查),也避免了使用try/catch块来处理这种条件。

如果你想知道操作是否真的删除了一个表或者它不存在,你可以检查响应的Status属性。

Response response = await tableClient.DeleteAsync();
if (response.Status == (int)HttpStatusCode.NotFound)
{
    // entity didn't exist)
}

RequestResult.TranslateFromExceptionMessage方法现在标记为[Obsolete],我想要一种方法来忽略404的自己。

根据你的提示检查RequestInformation.HttpStatusCode,我想出了以下内容:

try
{
    await table.ExecuteAsync(op);
}
catch (StorageException storEx)
{
    if (storEx.RequestInformation.HttpStatusCode != 404)
    {
        throw;
    }
}

在配置为使用Azure表存储时,在asp.net WebHooks项目中发现了类似的方法。请看Microsoft.Aspnet.WebHooks.custom.AzureStorage StorageManager类

我不确定这在你已经发现的基础上增加了多少,但是它们处理一切而不抛出异常,并且总是返回一个状态码,所以你可以在必要时对它做出反应。

这里的一个区别是它们将tableoperation传递给一个多用途的ExecuteAsync方法,而不是一个专门用于delete的方法,但这只是一个实现细节。

示例中的相关代码:

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

相关内容

  • 没有找到相关文章

最新更新