如何在Azure Blob存储中通过托管身份获取指定文件夹下的所有文件?(遇InvalidUri错误)
解决Azure Blob存储指定目录获取文件的问题
你遇到的400错误(InvalidUri)核心原因是对Azure Blob存储的「目录」概念理解有误,以及错误构造了容器客户端——Blob存储里没有真正的层级目录,所有文件都是扁平化存储在容器内的,所谓的“目录”只是Blob名称中的前缀(比如adf_exports/file.json里的adf_exports/就是前缀)。你之前把容器名和目录路径拼接后传给GetBlobContainerClient,相当于请求了一个不存在的容器(容器名称不允许包含/),所以服务器返回了无效URI的错误。
正确解决步骤
要获取指定“目录”下的文件,你需要:
- 先获取正确的容器客户端(只传入容器名称,不带目录路径);
- 在列出Blob时,通过
Prefix参数指定目标目录的前缀,以此筛选出该“目录”下的所有Blob。
修改后的完整代码
public async Task<IDictionary<string, DateTime>> GetBlobFiles(string directory = "adf_exports") { IDictionary<string, DateTime> files = new Dictionary<string, DateTime>(); try { var accountName = _configuration["StorageAccount"]; var blobEndpoint = $"https://{accountName}.blob.core.windows.net"; var credential = new DefaultAzureCredential(); BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(blobEndpoint), credential); // 1. 正确获取容器客户端:仅传入容器名称,不要拼接目录 var containerClient = blobServiceClient.GetBlobContainerClient(_configuration["BlobContainer"]); // 2. 构造规范的目录前缀:确保以/结尾,避免匹配到名称类似的非目标Blob string directoryPrefix = string.IsNullOrEmpty(directory) ? "" : $"{directory.TrimEnd('/')}/"; // 3. 列出指定前缀的Blob,includeSubdirectories设为false表示仅返回当前目录的直接文件 await foreach(BlobItem blob in containerClient.GetBlobsAsync( prefix: directoryPrefix, traits: BlobTraits.None, states: BlobStates.None, includeSubdirectories: false)) { // 建议使用Blob实际的最后修改时间,而非DateTime.Now,数据更准确 files.Add(blob.Name, blob.Properties.LastModified.GetValueOrDefault(DateTime.Now)); } return files; } catch (Exception ex) { // 建议添加日志记录,方便后续排查异常 return files; } }
关键细节说明
- 前缀格式:必须让前缀以
/结尾(比如adf_exports/),否则会误匹配到所有以adf_exports开头的Blob(比如adf_exportsFile.json这类不属于目标目录的文件)。 - IncludeSubdirectories参数:设为
true会返回目标目录及其所有子目录下的Blob;设为false则仅返回目标目录下的直接文件,按需选择即可。 - 身份验证兼容:这个修改完全适配你使用的托管身份(Managed Identity),不需要调整任何权限或认证逻辑。
内容的提问来源于stack exchange,提问作者Sandeep Thomas
相关产品推荐
相关产品推荐

