如何通过.NET获取Azure容器指定虚拟目录下的Blob文件列表?
问题分析与解决方案
两种实现的错误原因
第一种实现错误
你将容器级的SAS URL传给了BlobServiceClient,但该客户端要求的是存储账户的基础URL(格式为https://<account-name>.blob.core.windows.net,不带容器名和SAS参数)。后续又把虚拟目录路径当作容器名传给GetBlobContainerClient,服务器找不到对应资源,因此抛出The requested URI does not represent any resource on the server错误。
第二种实现错误
两个核心问题:
- SAS权限不足:你的SAS令牌中
sp=r仅包含读权限,而列出容器内Blob需要list权限(即sp参数需包含l,如sp=rl),因此返回未授权错误。 - 前缀格式错误:虚拟目录前缀
/test/datadrive/outbound/开头的斜杠多余,Azure Blob的前缀是Blob名称的起始部分,不需要开头斜杠,会导致匹配不到目标Blob。
正确实现方式
步骤1:确保SAS令牌具备正确权限
重新生成容器级SAS时,需勾选List权限,对应的sp参数值需包含l(例如sp=rl,同时保留读权限)。
步骤2:正确代码示例
var containerSasUrl = "https://<redacted>.blob.core.windows.net/<redacted>?sp=rl&st=202*-**-**T18:56:55Z&se=202*-**-**T03:56:55Z&spr=https&sv=202*-**-**&sr=c&sig=vlAq<redacted>%3D"; var targetPrefix = "test/datadrive/outbound/"; // 去掉开头的斜杠 var blobContainerClient = new BlobContainerClient(new Uri(containerSasUrl)); // 使用异步遍历处理分页结果,避免内存溢出 await foreach (var blobItem in blobContainerClient.GetBlobsAsync(prefix: targetPrefix)) { // 处理每个Blob,例如输出Blob名称 Console.WriteLine(blobItem.Name); }
额外说明
- 若无法重新生成带
list权限的SAS,可考虑使用存储账户密钥、托管身份等其他身份验证方式调用API。 GetBlobsAsync默认会返回所有匹配前缀的Blob(包括虚拟目录下的子目录),若需仅列出文件而非虚拟目录,可通过BlobItem.Properties.BlobType过滤(仅处理BlobType.BlockBlob)。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

