在Autodesk Forge Design Automation SDK中创建AppBundle遇NoSuchKey错误
解决Autodesk Forge Design Automation AppBundle包URL NoSuchKey错误
核心问题分析
你手动拼接的OSS对象URL未包含有效访问凭证,Design Automation服务无法直接访问私有OSS对象;另外如果使用临时Bucket,对象会被自动清理,也会触发该错误。
修复步骤
1. 使用持久化Bucket
确保上传Zip包的Bucket是持久化类型(创建时指定PolicyKey.Persistent),临时Bucket(Transient)内的对象会在24小时后被自动删除,后续访问必然失败。
2. 使用正确的Package地址(二选一)
不要手动拼接OSS URL,改用以下两种官方推荐的方式:
方式一:使用对象URN(推荐)
直接使用上传接口返回的objectId(URN格式),Design Automation服务可内部访问该对象,无需额外签名:
dynamic uploadResponse = await objectsApi.UploadObjectAsync( bucketKey, objectKey, (int)fileStream.Length, fileStream, "application/zip" ); // 用objectId作为Package字段值 var newVersion = new AppBundle { Id = fullyQualifiedId, Engine = $"Autodesk.Revit+{yearVersion}", Package = uploadResponse.objectId, Description = $"App bundle for Revit {yearVersion}", };
方式二:使用签名URL
生成带有效期的签名URL,确保Design Automation服务能访问到对象:
// 上传对象后生成签名URL(有效期1天) var signedUrlResponse = await objectsApi.CreateSignedResourceAsync( bucketKey, objectKey, new PostBucketsBucketKeyObjectsObjectKeySignedPost { Access = "read", Expires = 86400 } ); // 用签名URL作为Package字段值 var newVersion = new AppBundle { Id = fullyQualifiedId, Engine = $"Autodesk.Revit+{yearVersion}", Package = signedUrlResponse.SignedUrl, Description = $"App bundle for Revit {yearVersion}", };
3. 补充认证权限
认证时需添加Scope.DesignAutomation权限,确保服务间的访问权限有效:
dynamic tokenResponse = await auth.AuthenticateAsync( ClientId, ClientSecret, oAuthConstants.CLIENT_CREDENTIALS, new[] { Scope.DataRead, Scope.DataWrite, Scope.DesignAutomation } );
4. 验证对象状态
创建Alias后,可调用以下接口确认OSS对象仍存在:
// 检查对象是否存在 var objectDetails = await objectsApi.GetObjectDetailsAsync(bucketKey, objectKey);
完整修正代码示例
var auth = new TwoLeggedApi(); dynamic tokenResponse = await auth.AuthenticateAsync( ClientId, ClientSecret, oAuthConstants.CLIENT_CREDENTIALS, new[] { Scope.DataRead, Scope.DataWrite, Scope.DesignAutomation } ); var objectsApi = new ObjectsApi { Configuration = { AccessToken = tokenResponse.access_token } }; using var fileStream = new FileStream(zipFilePath, FileMode.Open, FileAccess.Read); dynamic uploadResponse = await objectsApi.UploadObjectAsync( bucketKey, objectKey, (int)fileStream.Length, fileStream, "application/zip" ); string fullyQualifiedId = $"{_account}.{bundleId}"; var newVersion = new AppBundle { Id = fullyQualifiedId, Engine = $"Autodesk.Revit+{yearVersion}", Package = uploadResponse.objectId, Description = $"App bundle for Revit {yearVersion}", }; AppBundle bundle = await _daClient.CreateAppBundleAsync(newVersion); // 创建并激活Alias var alias = new AppBundleAlias { Id = "prod", Version = fullyQualifiedId, Status = AppBundleAliasStatus.Active }; await _daClient.CreateAppBundleAliasAsync(_account, alias.Id, alias);
内容的提问来源于stack exchange,提问作者Ran P
相关产品推荐
相关产品推荐

