24 Oct 2024
Uploading a file to ACC using the .NET SDK
Introduction
In this blog, we'll cover the steps to upload a file to ACC using the APS .NET SDK.
You can find the libraries available at NuGet Gallery | AutodeskPlatformServices.SDK
For the scope of this blog, we'll use the Authentication, SDK Manager, OSS and Data Management.
How it works?
We need to go through the same steps described in the Upload a File tutorial.
In this sample we're going to focus in the steps from 3 to 8, as the steps 1 and 2 are covered by our Hubs Browser tutorial.
First thing we need to address is the configuration of the SDKmanager, clients and token generation
string client_id = Environment.GetEnvironmentVariable("client_id");
string client_secret = Environment.GetEnvironmentVariable("client_secret");
SDKManager sdkManager = SdkManagerBuilder
.Create() // Creates SDK Manager Builder itself.
.Build();
DataManagementClient _dmClient = new DataManagementClient(sdkManager);
AuthenticationClient _authClient = new AuthenticationClient(sdkManager);
OssClient _ossClient = new OssClient(sdkManager);
TwoLeggedToken twoLeggedToken = _authClient.GetTwoLeggedTokenAsync(client_id, client_secret, new List<Scopes>() { Scopes.DataRead, Scopes.DataWrite, Scopes.DataCreate }).GetAwaiter().GetResult();
Then we can start with the step three below:
3.Create a storage location: For this step we need to use the Data Management library through the DataManagementClient
.
private static Storage CreateStorage(DataManagementClient _dmClient, TwoLeggedToken twoLeggedToken, string project_id, string file_name, string folder_id)
{
StoragePayload payload = new StoragePayload()
{
Jsonapi = new ModifyFolderPayloadJsonapi()
{
_Version = VersionNumber._10
},
Data = new StoragePayloadData()
{
Type = Autodesk.DataManagement.Model.Type.Objects,
Attributes = new StoragePayloadDataAttributes()
{
Name = file_name,
},
Relationships = new StoragePayloadDataRelationships()
{
Target = new ModifyFolderPayloadDataRelationshipsParent()
{
Data = new ModifyFolderPayloadDataRelationshipsParentData()
{
Type = Autodesk.DataManagement.Model.Type.Folders,
Id = folder_id,
}
}
}
}
};
Storage storage = _dmClient.CreateStorageAsync(project_id, storagePayload: payload, accessToken: twoLeggedToken.AccessToken).GetAwaiter().GetResult();
return storage;
}
The next three steps are addressed together by one single SDK method.
5.Upload a file to the signed url
For these steps we need to use the OSS library through the OssClient
.
private static void ReadAndUploadFile(OssClient _ossClient, TwoLeggedToken twoLeggedToken, string file_path, string bucket_key, string object_key)
{
using (FileStream fileStream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
{
_ossClient.Upload(bucket_key, object_key, fileStream, accessToken: twoLeggedToken.AccessToken, CancellationToken.None).GetAwaiter().GetResult();
}
}
Now there's a tricky part.
We either create a new item (v1) or add a new version to an existing item.
In this sample, we're basically trying the first option, and in case an item with the same name already exists, an error with status 409 is thrown, then we can move to the second option.
If you use a three-legged token you can take advantage of the search endpoint
7.Create the first version of the uploaded file: For this step we need to use the Data Management library through the DataManagementClient
.
private static Item CreateNewItem(DataManagementClient _dmClient, TwoLeggedToken twoLeggedToken, string project_id, string file_name, string folder_id, Storage storage)
{
ItemPayload itemPayload = new ItemPayload()
{
Jsonapi = new ModifyFolderPayloadJsonapi()
{
_Version = VersionNumber._10
},
Data = new ItemPayloadData()
{
Type = Autodesk.DataManagement.Model.Type.Items,
Attributes = new ItemPayloadDataAttributes()
{
DisplayName = file_name,
Extension = new ItemPayloadDataAttributesExtension()
{
Type = Autodesk.DataManagement.Model.Type.ItemsautodeskBim360File,
_Version = VersionNumber._10
}
},
Relationships = new ItemPayloadDataRelationships()
{
Tip = new FolderPayloadDataRelationshipsParent()
{
Data = new FolderPayloadDataRelationshipsParentData()
{
Type = Autodesk.DataManagement.Model.Type.Versions,
Id = "1"
}
},
Parent = new FolderPayloadDataRelationshipsParent()
{
Data = new FolderPayloadDataRelationshipsParentData()
{
Type = Autodesk.DataManagement.Model.Type.Folders,
Id = folder_id
}
}
}
},
Included = new List<ItemPayloadIncluded>()
{
new ItemPayloadIncluded()
{
Type = Autodesk.DataManagement.Model.Type.Versions,
Id = "1",
Attributes = new ItemPayloadIncludedAttributes()
{
Name = file_name,
Extension = new ItemPayloadDataAttributesExtension()
{
Type = Autodesk.DataManagement.Model.Type.VersionsautodeskBim360File,
_Version = VersionNumber._10
}
},
Relationships = new ItemPayloadIncludedRelationships()
{
Storage = new FolderPayloadDataRelationshipsParent()
{
Data = new FolderPayloadDataRelationshipsParentData()
{
Type = Autodesk.DataManagement.Model.Type.Objects,
Id = storage.Data.Id,
}
}
}
}
}
};
Item newItem = _dmClient.CreateItemAsync(project_id, itemPayload: itemPayload, accessToken: twoLeggedToken.AccessToken).GetAwaiter().GetResult();
return newItem;
}
And in case we need to add a new version, we need to find the item id.
That's done with the method below:
private static string GetItemId(DataManagementClient _dmClient, TwoLeggedToken twoLeggedToken, string project_id, string folder_id, string file_name)
{
List<string> filterExtensionType = new List<string>() { "items:autodesk.bim360:File" };
FolderContents folderContents = _dmClient.GetFolderContentsAsync(project_id, folder_id, accessToken:twoLeggedToken.AccessToken, filterExtensionType: filterExtensionType).GetAwaiter().GetResult();
List<FolderContentsData> matchingItems = folderContents.Data.Where(d => d.Attributes.DisplayName == file_name).ToList();
int pageNumber = 0;
while (matchingItems.Count > 0 & !string.IsNullOrEmpty(folderContents.Links.Next?.Href)) {
pageNumber++;
folderContents = _dmClient.GetFolderContentsAsync(project_id, folder_id, accessToken: twoLeggedToken.AccessToken, filterExtensionType: filterExtensionType, pageNumber:pageNumber).GetAwaiter().GetResult();
matchingItems = folderContents.Data.Where(d => d.Attributes.DisplayName == file_name).ToList();
}
return matchingItems.First().Id;
}
With the item id we can move to creating a new version.
8.Update the version of a file: For this step we need to use the Data Management library through the _dmClient
.
private static void CreateNewVersion(DataManagementClient _dmClient, TwoLeggedToken twoLeggedToken, string project_id, string file_name, Storage storage, string item_id)
{
VersionPayload versionPayload = new VersionPayload()
{
Jsonapi = new ModifyFolderPayloadJsonapi()
{
_Version = VersionNumber._10
},
Data = new VersionPayloadData()
{
Type = Autodesk.DataManagement.Model.Type.Versions,
Attributes = new VersionPayloadDataAttributes()
{
Name = file_name,
Extension = new RelationshipRefsPayloadDataMetaExtension()
{
Type = Autodesk.DataManagement.Model.Type.VersionsautodeskBim360File,
_Version = VersionNumber._10
}
},
Relationships = new VersionPayloadDataRelationships()
{
Item = new FolderPayloadDataRelationshipsParent()
{
Data = new FolderPayloadDataRelationshipsParentData()
{
Type = Autodesk.DataManagement.Model.Type.Items,
Id = item_id
}
},
Storage = new FolderPayloadDataRelationshipsParent()
{
Data = new FolderPayloadDataRelationshipsParentData()
{
Type = Autodesk.DataManagement.Model.Type.Objects,
Id = storage.Data.Id,
}
}
}
}
};
Console.WriteLine(versionPayload.ToString());
ModelVersion newVersion = _dmClient.CreateVersionAsync(project_id, versionPayload: versionPayload, accessToken: twoLeggedToken.AccessToken).GetAwaiter().GetResult();
}
You can find the complete source code below: