【问题标题】:Trying to delete an Azure blob - getting blob does not exist exception尝试删除 Azure blob - 获取 blob 不存在异常
【发布时间】:2020-02-14 14:45:47
【问题描述】:

我有一个带有 blob (/images/filename) 的 Azure 存储容器。文件名(uri)在创建时存储在数据库中,来自文件上传保存函数:

        blob.UploadFromStream(filestream);
        string uri = blob.Uri.AbsoluteUri;
        return uri;

文件上传工作正常,当通过 SAS 密钥下载传递给客户端时也工作正常。

要删除图像我有一个从 MS 示例中获取的辅助函数:MS Github example 这是函数:

    internal bool DeleteFile(string fileURI)
    {
        try
        {
            Uri uri = new Uri(fileURI);
            string filename = Path.GetFileName(uri.LocalPath);
            CloudBlockBlob fileblob = container.GetBlockBlobReference(filename);
            fileblob.Delete();
            bool res = fileblob.DeleteIfExists();
            return res; //Ok
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex);
            return false;
        }

    }

这一切都在一个辅助类中,其开头如下:

public class AzureHelpers
{
    private string connection;
    private CloudStorageAccount storageAccount;
    private CloudBlobClient blobClient;
    private CloudBlobContainer container;


    public AzureHelpers()
    {
        connection = CloudConfigurationManager.GetSetting("myproject_AzureStorageConnectionString");
        storageAccount = CloudStorageAccount.Parse(connection);
        blobClient = storageAccount.CreateCloudBlobClient();
        container = blobClient.GetContainerReference(Resources.DataStoreRoot);
        container.CreateIfNotExists();
    }
 ....

我故意在 deleteIfExists 之前添加了 delete 以导致异常并证明我怀疑它没有找到文件/blob。

然而,当我单步执行代码时,CloudBlockBlob 肯定存在并且具有正确的 URI 等。

我想知道这是否可能是权限问题?还是我错过了什么?

【问题讨论】:

    标签: c# azure azure-blob-storage


    【解决方案1】:

    我认为您的容器中有一个目录。假设您有一个名为container_1 的容器,并且您的文件存储在类似/images/a.jpg 的目录中。在这里您应该记住,在这种情况下,您的 blob 名称是 images/a.jpg,而不是 a.jpg

    在您的代码中,Path.GetFileName 只获取a.jpg 之类的文件名,因此它与真实的blob 名称images/a.jpg 不匹配,从而导致错误“不存在”。

    所以在你的DeleteFile(string fileURI) 方法中,试试下面的代码,它在我这边运行良好:

    Uri uri = new Uri(fileURI);
    var temp = uri.LocalPath;
    string filename = temp.Remove(0, temp.IndexOf('/', 1)+1);
    CloudBlockBlob fileblob = container.GetBlockBlobReference(filename);
    //fileblob.Delete();
    bool res = fileblob.DeleteIfExists();
    

    或者使用这个代码sn-p:

    Uri uri = new Uri(fileURI);
    
    //use this line of code just to get the blob name correctly
    CloudBlockBlob blob_temp = new CloudBlockBlob(uri);
    
    var myblob = cloudBlobContainer.GetBlockBlobReference(blob_temp.Name);
    bool res = myblob.DeleteIfExists();
    

    【讨论】:

    • 谢谢伊万,就是这样。我确实在那里将图像作为子文件夹。干杯。
    【解决方案2】:

    似乎是权限问题,您能否转到门户,然后在 azure bolb 存储上编辑容器元数据。将访问私有更改为 public

    【讨论】:

    • 好的,我可以在早上做这件事,但如果这有效,表明这是一个访问问题,我该如何从服务器调用中做到这一点。我不想让它公开..?我是否使用附加到 URI 的 SAS 密钥?还是?
    • 我不认为将容器设置为公共会有帮助,因为公共容器只能允许对 blob 进行匿名读取操作,不允许对 blob 或容器进行匿名删除操作。另外,Brett 已经在使用连接字符串来构建客户端了,应该是拥有完全权限的。
    猜你喜欢
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 2018-05-07
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多