如何通过C#的BlobContainerClient获取Azure Blob的实际访问域名?
环境:C#、Visual Studio 2022
我通过BlobContainerClient获取Azure存储账户容器中的Blob列表,使用常规代码生成的Blob链接(与Azure容器控制台显示的链接一致)无法下载文件:
代码片段:
var resultSegment = container.GetBlobsByHierarchyAsync(prefix: prefix, delimiter: "/") .AsPages(default, 50); // 枚举每页返回的Blob await foreach (Azure.Page<BlobHierarchyItem> blobPage in resultSegment) { // 分层列表可能返回虚拟目录和Blob foreach (BlobHierarchyItem blobhierarchyItem in blobPage.Values) { url = $"{container.Uri}/{blobhierarchyItem.Blob.Name}"; // 这里生成的是存储账户原生Blob端点链接 } }
生成的链接示例:
https://someappclients.blob.core.windows.net/$mycontainer/somepath/somefile.pdf
访问该链接返回错误:
<Error> <Code>ResourceNotFound</Code> <Message>The specified resource does not exist. RequestId:b3002409-901e-009e-38dd-0858d9000000 Time:2022-12-05T19:11:59.4423847Z</Message> </Error>
而实际可正常下载的Blob链接使用的是自定义域名:https://a-nice-prefix.the-real-domain.com/somepath/somefile.pdf
请问能否通过BlobServiceClient、BlobContainerClient或Azure管理API获取该Blob对应的实际访问域名?
解决方案说明
Azure存储的原生Blob端点(xxx.blob.core.windows.net)和你实际使用的自定义域名,本质是DNS层面的CNAME绑定关系。BlobServiceClient或BlobContainerClient这类数据平面SDK不会直接返回自定义域名,因为这属于存储账户的管理配置信息,而非Blob本身的属性。你可以通过以下两种方式获取:
1. 通过Azure管理API(Resource Manager SDK)动态获取
使用Azure Resource Manager的存储账户管理SDK,读取存储账户的自定义域名配置,再拼接成Blob的访问链接:
- 首先安装NuGet包:
Azure.ResourceManager.Storage - 示例代码:
using Azure.Identity; using Azure.ResourceManager; using Azure.ResourceManager.Storage; // 初始化ARM客户端(使用默认Azure凭据,需确保程序有存储账户的读取权限) var armClient = new ArmClient(new DefaultAzureCredential()); // 替换为你的存储账户资源ID string storageAccountResourceId = "/subscriptions/{你的订阅ID}/resourceGroups/{资源组名}/providers/Microsoft.Storage/storageAccounts/{存储账户名}"; var storageAccount = armClient.GetStorageAccountResource(new Azure.Core.ResourceIdentifier(storageAccountResourceId)); // 获取存储账户属性,提取自定义域名配置 var accountProperties = await storageAccount.GetAsync(); var customDomainConfig = accountProperties.Value.Data.CustomDomain; if (customDomainConfig != null) { // 拼接完整自定义域名(需根据实际DNS绑定情况调整格式) string customBlobEndpoint = $"https://{customDomainConfig.Name}.the-real-domain.com"; // 生成Blob的自定义域名访问链接 string blobCustomUrl = $"{customBlobEndpoint}/{container.Name}/{blobhierarchyItem.Blob.Name}"; }
注意:
customDomainConfig.Name是你在Azure存储账户中配置的自定义域名前缀,完整域名需要结合你绑定的根域名拼接(比如前缀是a-nice-prefix,根域名是the-real-domain.com,则完整域名是a-nice-prefix.the-real-domain.com)。
2. 预先配置读取自定义域名
如果你的自定义域名是固定不变的,直接将其写入应用配置文件(如appsettings.json),在代码中读取后拼接Blob路径即可,无需通过API动态获取。
补充说明
你遇到的原生链接访问报错,大概率是因为存储账户配置了私有访问(如容器设为私有、IP防火墙限制),而自定义域名可能绑定了CDN或配置了允许访问的网络策略,因此可以正常访问。
内容的提问来源于stack exchange,提问作者Robert Achmann

