C# 删除 Azure Blob - 无效的 Uri

C# Delete Azure Blob - Invalid Uri

我正在尝试删除文件夹结构的 Azure blob 容器:

MyStorageAccount > MyContainer > MySubfolder > Blob 列表

我想删除包含其中所有 blob 的子文件夹 我的子文件夹 > Blob 列表

URI:

*********** blobUri:https://myapp.blob.core.windows.net/containerID/subFolderID

containerID 和 subfolderID 是正确的,我已经在 Azure 门户中查看了。

调试时出现此错误。为什么我的 Uri 无效?

Exception thrown: 'Azure.RequestFailedException' in System.Private.CoreLib.dll
HTTP error code 400: InvalidUri
The requested URI does not represent any resource on the server.
RequestId:1af585de-1234-00yy-0ce1-50xxxx000000
Time:2022-04-15T15:56:47.0801054Z
Status: 400 (The requested URI does not represent any resource on the server.)
ErrorCode: InvalidUri

我的 DeleteBlobs class

using Azure;
using Azure.Storage;
using Azure.Storage.Blobs;
using MyApp.Data;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;

namespace MyApp.Areas.FunctionalLogic
{
    public class DeleteBlobs
    {
        private readonly DBConnectionStringFactory _DBConnectionStringFactory = new();

        public async Task<bool> DeleteAzureBlobAsync(string containerID, string subFolderID)
        {
            string connectionString = getConnectionString();
            var blobUri = getBlobUri(containerID, subFolderID).ToString();
            Debug.WriteLine("*********** blobUri:" + blobUri);
            BlobServiceClient container = new BlobServiceClient(connectionString);

            try
            {
                await container.DeleteBlobContainerAsync(blobUri);
            }
            catch (RequestFailedException e)
            {
                Debug.WriteLine("HTTP error code {0}: {1}", e.Status, e.ErrorCode);
                Debug.WriteLine(e.Message);
            }
            return true;
        }

        public string getConnectionString()
        {
            string connecString = Environment.GetEnvironmentVariable("MY_CONNECTION_STRING");
            return connecString;
        }

        public Uri getBlobUri(string containerName, string subFolderName)
        {
            Uri blobUri = new Uri("https://" + "myapp.blob.core.windows.net/" + containerName + "/" + subFolderName);

            return blobUri;
        }

    }
}

更新答案:

   public async Task<bool> DeleteAzureBlobAsync(string containerID, string subFolderID)
    {
        string connectionString = getConnectionString();
        BlobContainerClient blobContainer = createContainerClient(connectionString, containerID);
        try
        {
            var resultSegment = blobContainer.GetBlobsAsync().AsPages();

            await foreach (Page<BlobItem> blobPage in resultSegment)
            {
                foreach (BlobItem blobItem in blobPage.Values)
                {
                    string blobName = blobItem.Name;
                    string processedName = blobName.Remove(blobName.LastIndexOf('/'));

                    if(processedName == subFolderID)
                    {
                        Debug.WriteLine("Delete: " + blobName);
                        await blobContainer.DeleteBlobAsync(blobName);
                    }
                }
            }
        }
        catch (RequestFailedException e)
        {
            Debug.WriteLine(e.Message);
            throw;
        }

        return true;
    }

    public BlobContainerClient createContainerClient(string connectionString, string containerName)
    {
        var containerClient = new BlobContainerClient(connectionString, containerName);
        return containerClient;
    }

你不能,因为 Azure blob 存储中并不真正存在文件夹;它们只是根据 blob 的名称显示给用户。

要删除“文件夹”,请删除其中的所有 blob(和 sub-folders)。

Blob 存储中没有子文件夹。你有 Container,那么剩下的都是 blob 名称的一部分。

您需要做的是根据前缀('subfolder' 名称)列出 blob:

var blobs = blobContainer.ListBlobs(prefix = subFolderName, bool useFlatBlobListing = true);

然后,对于每个匹配项,删除 blob。

更新:

url 可能无效,也可能无效,问题是因为您在应该仅传递 blob 名称时传递 Uri:

public virtual System.Threading.Tasks.Task<Azure.Response> DeleteBlobAsync (string blobName, Azure.Storage.Blobs.Models.DeleteSnapshotsOption snapshotsOption = Azure.Storage.Blobs.Models.DeleteSnapshotsOption.None, Azure.Storage.Blobs.Models.BlobRequestConditions conditions = default, System.Threading.CancellationToken cancellationToken = default);

来源:https://docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs.blobcontainerclient.deleteblobasync?view=azure-dotnet