简体   繁体   English

在c#中从Windows azure中删除blob

[英]Delete a blob from Windows azure in c#

I have code which inserts a blob into storage, and allows the user to view a list of the blobs, and an individual blob. 我有代码将blob插入存储,并允许用户查看blob列表和单个blob。 However, I now can't get the blob to delete, the error that appears is 但是,我现在无法删除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." “System.ServiceModel.ni.dll中出现'System.ServiceModel.FaultException`1'类型的异常,但未在用户代码中处理。附加信息:远程服务器返回错误:(404)Not Found。”

The code in the WCF service is 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();
}

and then I access this in the mobile client application through SOAP services like: 然后我通过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);
    }
}

I also use SAS token to save the blob in the first place - I don't know whether this makes a difference? 我也首先使用SAS令牌来保存blob - 我不知道这是否有所作为?

In Azure Storage Client Library 4.0, we changed Get*Reference methods to accept relative addresses only. 在Azure Storage Client Library 4.0中,我们更改了Get * Reference方法以仅接受相对地址。 So, if you are using the latest library and the parameter "uri" is an absolute address, you should change it to either to the blob name or you should use the CloudBlockBlob constructor that takes an Uri and a StorageCredentials object. 因此,如果您使用的是最新的库且参数“uri”是绝对地址,则应将其更改为blob名称,或者应使用带有Uri和StorageCredentials对象的CloudBlockBlob构造函数。

Please see all such breaking changes in our GitHub repository . 请在我们的GitHub存储库中查看所有这些重大更改。

I am using WindowsAzure.Storage (v8.1.4) in my ASP.NET Core MVC web app (v1.1.3). 我在我的ASP.NET核心MVC Web应用程序(v1.1.3)中使用WindowsAzure.Storage (v8.1.4)。

I have an image crop and resize feature on my web app so I decide to use Azure Blob Storage to store the raw(user uploaded) pictures and the cropped (after resize) pictures. 我在我的网络应用程序上有一个图像裁剪和调整大小功能,所以我决定使用Azure Blob存储来存储原始(用户上传的)图片和裁剪(调整大小后)图片。

One important thing to keep in mind even you're using the CloudBlockBlob constructor with the absolute uri is that you still need to pass your storage account credentials into CloudBlockBlob constructor. 即使您将CloudBlockBlob构造函数与绝对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;
    }
}

Hope this helps. 希望这可以帮助。

In Azure Storage Client Library 4.0, the get Reference method must be changed to accept relative addresses and nothing else . 在Azure Storage Client Library 4.0中,必须更改get Reference方法以接受相对地址而不接受任何其他地址。 So, this does not support the libraries earlier than that, 所以,这不支持早于此的库,

you should change it to either to the blob name or you should use the CloudBlockBlob constructor that takes an Uri and a StorageCredentials object. 您应该将其更改为Blob名称,或者您应该使用带有Uri和StorageCredentials对象的CloudBlockBlob构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM