VB.NET调用Await client.GetSecretAsync后出现空引用异常
问题场景
在Public Async Sub Main()模块方法中执行以下代码时,调用Await client.GetSecretAsync(KEY_ID)后立即触发**“Object reference not set to an instance of an object”**错误,但后续仍能正常通过secret.Value.Value获取到目标密钥内容:
Dim kvUri = $"https://{KEY_VAULT_NAME}.vault.azure.net" Dim client = New SecretClient(New Uri(kvUri), New DefaultAzureCredential()) Dim secret = Await client.GetSecretAsync(KEY_ID)
错误原因
这个空引用错误并非来自GetSecretAsync方法本身,也不是返回的secret对象为空,而是**DefaultAzureCredential内部的认证流程导致**:
DefaultAzureCredential会自动依次尝试多种认证方式(环境变量、托管标识、Azure CLI、Visual Studio/Visual Studio Code等),当其中某一种认证方式的内部逻辑触发空引用异常,但后续其他认证方式成功完成认证时,就会出现“先抛出错误但最终操作成功”的矛盾现象。
比如本地开发时,Azure CLI未登录但Visual Studio已关联有效Azure账号,Credential会先尝试CLI认证路径并触发空引用,随后自动切换到Visual Studio认证路径并成功,最终能拿到密钥,但中间的空引用错误会被抛出。
解决方法
1. 明确指定认证方式
避免DefaultAzureCredential遍历所有认证路径,根据运行环境直接指定对应认证方式,减少不必要的异常触发:
- 本地开发场景(使用Visual Studio认证):
Dim kvUri = $"https://{KEY_VAULT_NAME}.vault.azure.net" Dim client = New SecretClient(New Uri(kvUri), New VisualStudioCredential()) Dim secret = Await client.GetSecretAsync(KEY_ID)
- 生产环境(使用托管标识):
Dim kvUri = $"https://{KEY_VAULT_NAME}.vault.azure.net" Dim client = New SecretClient(New Uri(kvUri), New ManagedIdentityCredential()) Dim secret = Await client.GetSecretAsync(KEY_ID)
2. 过滤认证过程中的非致命错误
如果必须使用DefaultAzureCredential,可以通过异常捕获忽略认证阶段的空引用错误,只处理最终密钥获取失败的情况:
Dim kvUri = $"https://{KEY_VAULT_NAME}.vault.azure.net" Dim client = New SecretClient(New Uri(kvUri), New DefaultAzureCredential()) Try Dim secret = Await client.GetSecretAsync(KEY_ID) ' 正常处理密钥内容 Catch ex As NullReferenceException ' 仅在确认密钥未成功获取时执行错误处理 ' 可结合检查secret是否为null判断 End Try
3. 规范本地开发环境的认证状态
确保本地常用认证工具处于正常状态:
- 登录Azure CLI(执行
az login) - 确认Visual Studio/VS Code已关联正确的Azure账号
这样DefaultAzureCredential会优先使用正常的认证方式,减少异常触发的概率。
内容的提问来源于stack exchange,提问作者user25399617

