You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Blob名称合法时生成SAS URL报资源名含无效字符如何解决

问题根因&解决方案

你遇到的这个报错90%以上是SAS生成过程中资源路径被二次编码、或者SDK版本/签名方式错误导致的,按以下步骤排查修复即可:

第一步:先修复已知的SDK使用问题

  • 先把项目引用的Azure.Storage.Blobs NuGet包升级到最新稳定版,12.10.0之前的版本存在多个虚拟目录Blob(即带/路径的Blob)SAS生成的编码bug,会直接导致资源名解析失败。
  • 不要手动填充BlobSasBuilder的容器名、Blob名、资源类型字段,直接用SDK提供的简易重载方法,避免手动赋值出错,代码简化为:
var container = _blobServiceClient.GetBlobContainerClient("files");
// 注意:容器名必须全小写,Azure存储不支持大写命名容器
var client = container.GetBlobClient("dev-test/test-json.txt");

if (!client.CanGenerateSasUri)
    return string.Empty;

// 直接传入权限和过期时间,SDK会自动补全所有SAS必填字段,不需要手动构建
Uri sasUri = client.GenerateSasUri(BlobSasPermissions.Read, DateTimeOffset.UtcNow.AddDays(1));
// 取AbsoluteUri返回,不要用ToString(),避免.NET自动解码已编码的特殊字符
return sasUri.AbsoluteUri;

第二步:检查签名方式是否匹配你的认证模式

如果你是参考托管身份教程实现的,说明你是用AAD凭证(比如DefaultAzureCredential、托管身份)初始化的BlobServiceClient,不是用存储账户连接字符串,这种场景下你不能直接生成SAS,必须先获取用户委托密钥,否则SDK会生成格式看似正确、但签名完全无效的令牌,触发各种无意义的解析报错,正确代码如下:

// 先获取用户委托密钥,有效期必须覆盖SAS的有效期
var delegationKey = await _blobServiceClient.GetUserDelegationKeyAsync(
    DateTimeOffset.UtcNow, 
    DateTimeOffset.UtcNow.AddDays(1)
);

var container = _blobServiceClient.GetBlobContainerClient("files");
var client = container.GetBlobClient("dev-test/test-json.txt");

if (!client.CanGenerateSasUri)
    return string.Empty;

var builder = new BlobSasBuilder
{
    StartsOn = DateTimeOffset.UtcNow,
    ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
    Protocol = SasProtocol.Https
};
builder.SetPermissions(BlobSasPermissions.Read);
// 绑定用户委托密钥,用AAD凭证签名
builder.AddSasSignature(_blobServiceClient.AccountName, delegationKey);

Uri sasUri = client.GenerateSasUri(builder);
return sasUri.AbsoluteUri;

第三步:排查二次编码问题

如果改完以上代码还是报错,直接打印生成的完整SAS URL,检查Blob路径部分:

  • 正常的路径分隔符应该是明文/,或者编码为%2F
  • 如果出现%252F,说明路径里的斜杠被二次编码了,Azure存储会把%25识别为非法字符,直接抛出「指定的资源名称包含无效字符」错误。
  • 二次编码通常是因为你对SDK返回的完整URL额外调用了HttpUtility.UrlEncode、或者接口序列化时自动做了全量URL转义,删掉所有额外的编码逻辑即可,SDK返回的AbsoluteUri已经是符合规范的编码格式,不需要再做任何处理。

对比你贴的两个SAS令牌,参数本身没有格式错误,问题一定出在完整URL的资源路径部分、或者签名逻辑上,和Blob有没有后缀、虚拟目录层级没有关系。

内容的提问来源于stack exchange,提问作者Dror Cohen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 23:18:09