在 c# 中从 Windows azure 中删除一个 blob

Delete a blob from Windows azure in c#

我有将 blob 插入存储的代码,并允许用户查看 blob 列表和单个 blob。但是,我现在无法删除 blob,出现的错误是

"An exception of type 'System.ServiceModel.FaultException`1' occurred in System.ServiceModel.ni.dll but was not handled in user code. Additional information: The remote server returned an error: (404) Not Found."

WCF 服务中的代码是

public void DeleteBlob(string guid, string uri)
{
    //create the storage account with shared access key
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(accountDetails);

    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference(guid);

    CloudBlockBlob blob = container.GetBlockBlobReference(uri);
    blob.DeleteIfExists();
}

然后我通过 SOAP 服务在移动客户端应用程序中访问它,例如:

private void mnuDelete_Click(object sender, EventArgs e)
{
    MessageBoxResult message = MessageBox.Show("Are you sure you want to delete this image?", "Delete", MessageBoxButton.OKCancel);
    if (message == MessageBoxResult.OK)
    {
        Service1Client svc = new Service1Client();
        svc.DeleteBlobCompleted += new EventHandler<AsyncCompletedEventArgs>(svc_DeleteBlobCompleted);
        svc.DeleteBlobAsync(container, uri);
    }
}
void svc_DeleteBlobCompleted(object sender, AsyncCompletedEventArgs e)
{
    if (e.Error == null) {
        NavigationService.Navigate(new Uri("/Pages/albums.xaml", UriKind.Relative));
    }
    else {
        MessageBox.Show("Unable to delete this photo at this time", "Error", MessageBoxButton.OK);
    }
}

我也首先使用 SAS 令牌来保存 blob - 我不知道这是否有所作为?

在 Azure 存储客户端库 4.0 中,我们更改了 Get*Reference 方法以仅接受相对地址。因此,如果您使用的是最新的库并且参数 "uri" 是绝对地址,您应该将其更改为 blob 名称或者您应该使用 CloudBlockBlob constructor that takes an Uri and a StorageCredentials 对象。

请在我们的 GitHub repository 中查看所有此类重大更改。

我在 ASP.NET 核心 MVC 网络应用程序 (v1.1.3) 中使用 WindowsAzure.Storage (v8.1.4)

我的 Web 应用程序具有图像裁剪和调整大小功能,因此我决定使用 Azure Blob 存储来存储原始(用户上传)图片和裁剪后(调整大小后)的图片。

即使您使用带有绝对 uri 的 CloudBlockBlob 构造函数,也要记住一件重要的事情是您仍然需要将存储 帐户凭据 传递到CloudBlockBlob构造函数。

public class AzureBlobStorageService : IBlobStorageService
{
    private readonly AzureBlobConnectionConfigurations _azureBlobConnectionOptions;
    private readonly CloudStorageAccount _storageAccount;
    private readonly CloudBlobClient _blobClient;

    public AzureBlobStorageService(IOptions<AzureBlobConnectionConfigurations> azureBlobConnectionAccessor)
    {
        _azureBlobConnectionOptions = azureBlobConnectionAccessor.Value;

        _storageAccount = CloudStorageAccount.Parse(_azureBlobConnectionOptions.StorageConnectionString);
        _blobClient = _storageAccount.CreateCloudBlobClient();
    }

    public async Task<Uri> UploadAsync(string containerName, string blobName, IFormFile image)
    {
        ...
    }

    public async Task<Uri> UploadAsync(string containerName, string blobName, byte[] imageBytes)
    {
        ...
    }

    public async Task<byte[]> GetBlobByUrlAsync(string url, bool deleteAfterFetch = false)
    {
        // This works
        var blockBlob = new CloudBlockBlob(new Uri(url), _storageAccount.Credentials);

        // Even this will fail
        //var blockBlob = new CloudBlockBlob(new Uri(url));

        await blockBlob.FetchAttributesAsync();

        byte[] arr = new byte[blockBlob.Properties.Length];
        await blockBlob.DownloadToByteArrayAsync(arr, 0);

        if (deleteAfterFetch)
        {
            await blockBlob.DeleteIfExistsAsync();
        }

        return arr;
    }

    private async Task<CloudBlobContainer> CreateContainerIfNotExistAsync(string containerName)
    {
        var container = _blobClient.GetContainerReference(containerName);
        if (!await container.ExistsAsync())
        {
            await container.CreateAsync();
            await container.SetPermissionsAsync(new BlobContainerPermissions
            {
                PublicAccess = BlobContainerPublicAccessType.Blob
            });
        }

        return container;
    }
}

希望对您有所帮助。

在 Azure Storage Client Library 4.0 中,get Reference 方法必须更改为接受相对地址,而不接受其他任何内容。所以,这不支持更早的库,

您应该将其更改为 blob 名称,或者您应该使用采用 Uri 和 StorageCredentials 对象的 CloudBlockBlob 构造函数。