How do I deserialize DynamicJsonResponse content into objects with .NET Autodesk.Forge API calls?

How do I deserialize DynamicJsonResponse content into objects with .NET Autodesk.Forge API calls?

Anonymous
Not applicable
1,424 Views
1 Reply
Message 1 of 2

How do I deserialize DynamicJsonResponse content into objects with .NET Autodesk.Forge API calls?

Anonymous
Not applicable

I would like to build some tools that let me browse our BIM 360 hubs, projects, folders, and items. Right now I'm just trying to prototype and see what's possible. I've successfully called against Forge with HTTP GET and POST using Postman and tokens I've generated.

 

When I build API clients I typically create classes representing the business objects that the API returns, and then use a json deserializer to populate a collection of them on GET. When I want to POST I serialize objects back to json.

 

I'm reviewing various samples on Autodesk-Forge's GitHub and it initially seemed as though the best path forward for a .NET application was to use NuGet Autodesk.Forge which provided various API-calling objects (HubsApi, ProjectsApi, FoldersApi, etc.). The NuGet also provides objects... Hub, Project, etc. Cool. Maybe I can get these, throw them into ViewModels, and do something with them?

 

I can setup a two-legged token and can use GET, but the response comes back as DynamicJsonResponse. Okay. So far I've found...

  1. The API object returns DynamicJsonResponse.
  2. The DynamicJsonResponse has a Dictionary, and I care about the entry with the key "data"
  3. This is a DynamicDictionary
  4. It has an element within itself that eventually describes the attributes of the Hub.
  5. Nothing so far indicates that I can just get a "Hub" object

 

 

 

Scope[] scopes = new Scope[] { Scope.DataRead, Scope.DataWrite, Scope.BucketCreate, Scope.BucketRead };

oauth2TwoLegged = new TwoLeggedApi();
			twoLeggedCredentials = oauth2TwoLegged.Authenticate(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, oAuthConstants.CLIENT_CREDENTIALS, scopes);

HubsApi hubsApi = new HubsApi();
hubsApi.Configuration.AccessToken = twoLeggedCredentials.access_token;
dynamic response = hubsApi.GetHubs();
DynamicDictionary innerDictionary = (DynamicDictionary)((DynamicJsonResponse)response).Dictionary["data"];

 

 

 

This appears to be the case with each of the API objects. I've gone through a few of the .NET sample projects (one is WPF, one is Windows Forms, one is ASP.NET MVC) and they all seem to make Forge calls a little differently.

 

I feel like I'm missing something. Shouldn't I be able to deserialize the resulting json from HubsApi into a Hub? Or from ProjectsApi into a Project? Is there an easy way to do this? Also - all the same questions to serialize data and push it back to BIM 360.

0 Likes
1,425 Views
1 Reply
Reply (1)
Message 2 of 2

Anonymous
Not applicable

Not long after I created this thread I was able to make some progress. For the purposes of education, I am trying to see how to navigate to a specific hub, BIM 360 project, and folder in order to read a list of items (files) in that folder. Everything works up through accessing the name of the item itself. I'm having some trouble converting the json-based objects into the Item class and being able to use its attributes to pull out the file name. I've included below what I was able to get to sort-of work. I don't know if this is "correct", but it does run.

 

I am aware that many of the "get" methods have a filter option. I'm currently not using it and am instead depending on LINQ to filter results. The conversion with the ToObject<T> methods appears to run slowly - I may try filtering in the "get" methods to reduce the amount of json that ToObject<T> has to parse.

 

string targetHubName = "my_company_name";
string targetBIM360ProjectName = "my_project_name";
string targetRootFolder = "Project Files";
string targetProjectFilesFolder = "my_subfolder_name";
string targetApiCollectionType = "items";

// Get the hub
DynamicJsonResponse hubsResponse = hubsApi.GetHubs();
Hubs hubCollection = hubsResponse.ToObject<Hubs>();
Hub hub = hubCollection.Data.Where(h => h.Attributes.Name == targetHubName).FirstOrDefault();

// Get the project
DynamicJsonResponse projectsResponse = projectsApi.GetHubProjects(hub.Id);
Projects projectCollection = projectsResponse.ToObject<Projects>();
Project project = projectCollection.Data.Where(p => p.Attributes.Name == targetBIM360ProjectName).FirstOrDefault();
					
// Get Project Files
DynamicJsonResponse toplevelFoldersResponse = projectsApi.GetProjectTopFolders(hub.Id, project.Id);
TopFolders topFolderCollection = toplevelFoldersResponse.ToObject<TopFolders>();
Folder topLevelFolder = topFolderCollection.Data.Where(f => f.Attributes.Name == targetRootFolder).FirstOrDefault();
					
// Get a subfolder of Project Files
DynamicJsonResponse subFolderResponse = foldersApi.GetFolderContents(project.Id, topLevelFolder.Id);
TopFolders subFolderCollection = subFolderResponse.ToObject<TopFolders>();
Folder subFolder = subFolderCollection.Data.Where(f => f.Attributes.Name == targetProjectFilesFolder).FirstOrDefault();

// Get Items (files) in folder
DynamicJsonResponse folderContentsResponse = foldersApi.GetFolderContents(project.Id, subFolder.Id);
JsonApiCollection apiCollection = folderContentsResponse.ToObject<JsonApiCollection>();

List<JsonApiResource> itemResources = apiCollection.Data.Where(d => d.Type == targetApiCollectionType).ToList();

// Trying to get details about the item (file)
foreach (JsonApiResource resource in itemResources)
{
	// Get more detail about the specific item
	DynamicJsonResponse itemsResponse = itemsApi.GetItem(project.Id, resource.Id);

	// Extract json attributes
	DynamicDictionary itemDictionary = (DynamicDictionary)(itemsResponse.Dictionary["data"]);
	DynamicDictionary fileAttributes = (DynamicDictionary)(itemDictionary.Dictionary["attributes"]);

	string itemFileName = fileAttributes.Dictionary["displayName"].ToString();

	Console.WriteLine("Filename: " + itemFileName);
}