This .Net SDK enables you to easily integrate the Forge REST APIs into your application, including OAuth, Data Management, Model Derivative, and Design Automation.
- .NET Framworks 4.5.2 or later
- .NET Core 2.0 or later
- A registered app on the Forge Developer portal.
- Building the API client library requires Visual Studio 2015 to be installed.
The DLLs included in the package may not be the latest version. We recommend using NuGet to obtain the latest version of the packages:
Install-Package RestSharp
Install-Package Newtonsoft.Json
Run the following command to generate the DLL:
- [Mac/Linux]
/bin/sh build.sh
- [Windows]
build.bat
Install nuget CLI, generate an API Key and save. Build application in Release
mode. Run the following (CLI):
nuget pack \paht\to\forge-api-dotnet-client\src\Autodesk.Forge\Autodesk.Forge.nuspec -build
nuget push \path\to\Autodesk.Forge.1.1.0.nupkg -Source \\mycompany\repo\
To install the API client library to your local application, simply execute:
Install-Package Autodesk.Forge
For a complete tutorial, please visit Learn Forge tutorial.
Follow this tutorial to see a step-by-step authentication guide, and examples of how to use the Forge APIs.
Create an app on the Forge Developer portal. Note the client key and client secret.
This SDK comes with an OAuth 2.0 client that allows you to retrieve 2-legged and 3-legged tokens. It also enables you to refresh 3-legged tokens. This tutorial uses both 2-legged and 3-legged tokens for calling different Data Management endpoints.
This type of token is given directly to the application. To get a 2-legged token run the following code:
using Autodesk.Forge;
using Autodesk.Forge.Client;
using Autodesk.Forge.Model;
namespace my_namespace {
class my_class {
// Initialize the oAuth 2.0 client configuration fron enviroment variables
// you can also hardcode them in the code if you want in the placeholders below
private static string FORGE_CLIENT_ID =Environment.GetEnvironmentVariable ("FORGE_CLIENT_ID")?? "your_client_id" ;
private static string FORGE_CLIENT_SECRET =Environment.GetEnvironmentVariable ("FORGE_CLIENT_SECRET")?? "your_client_secret" ;
private static Scope[] _scope =new Scope[] { Scope.DataRead, Scope.DataWrite } ;
// Intialize the 2-legged oAuth 2.0 client.
private static TwoLeggedApi _twoLeggedApi =new TwoLeggedApi () ;
// Synchronous example
internal static dynamic _2leggedSynchronous () {
try {
// Call the synchronous version of the 2-legged client with HTTP information
// HTTP information will help you to verify if the call was successful as well
// as read the HTTP transaction headers.
ApiResponse<dynamic> bearer =_twoLeggedApi.AuthenticateWithHttpInfo (FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, oAuthConstants.CLIENT_CREDENTIALS, _scope) ;
if ( bearer.StatusCode != 200 )
throw new Exception ("Request failed! (with HTTP response " + bearer.StatusCode + ")") ;
// The JSON response from the oAuth server is the Data variable and has been
// already parsed into a DynamicDictionary object.
return (bearer.Data) ;
} catch ( Exception /*ex*/ ) {
return (null) ;
}
}
public static void Test () {
dynamic bearer =_2leggedSynchronous () ;
if ( bearer == null ) {
Console.WriteLine ("You were not granted a new access_token!") ;
return ;
}
// The call returned successfully and you got a valid access_token.
string token =bearer.token_type + " " + bearer.access_token ;
Console.WriteLine ("Your synchronous token test is: " + token) ;
// ...
}
// Asynchronous example (recommended)
internal static async Task<dynamic> _2leggedAsync () {
try {
// Call the asynchronous version of the 2-legged client with HTTP information
// HTTP information will help you to verify if the call was successful as well
// as read the HTTP transaction headers.
ApiResponse<dynamic> bearer =await _twoLeggedApi.AuthenticateAsyncWithHttpInfo (FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, oAuthConstants.CLIENT_CREDENTIALS, _scope) ;
//if ( bearer.StatusCode != 200 )
// throw new Exception ("Request failed! (with HTTP response " + bearer.StatusCode + ")") ;
// The JSON response from the oAuth server is the Data variable and has been
// already parsed into a DynamicDictionary object.
return (bearer.Data) ;
} catch ( Exception /*ex*/ ) {
return (null) ;
}
}
public async static void TestAsync () {
if ( bearer == null ) {
Console.WriteLine ("You were not granted a new access_token!") ;
return ;
}
// The call returned successfully and you got a valid access_token.
string token =bearer.token_type + " " + bearer.access_token ;
Console.WriteLine ("Your async token test is: " + token) ;
// ...
}
}
}
To ask for permissions from a user to retrieve an access token, you redirect the user to a consent page. Run this code to create a consent page URL:
using Autodesk.Forge;
using Autodesk.Forge.Client;
namespace my_namespace {
class my_class {
// Initialize the oAuth 2.0 client configuration fron enviroment variables
// you can also hardcode them in the code if you want in the placeholders below
private static string FORGE_CLIENT_ID =Environment.GetEnvironmentVariable ("FORGE_CLIENT_ID")?? "your_client_id" ;
private static string FORGE_CLIENT_SECRET =Environment.GetEnvironmentVariable ("FORGE_CLIENT_SECRET")?? "your_client_secret" ;
private static string PORT =Environment.GetEnvironmentVariable ("PORT")?? "3006" ;
private static string FORGE_CALLBACK =Environment.GetEnvironmentVariable ("FORGE_CALLBACK")?? "http://localhost:" + PORT + "/oauth" ;
private static Scope[] _scope =new Scope[] { Scope.DataRead, Scope.DataWrite } ;
// Intialize the 3-legged oAuth 2.0 client.
private static ThreeLeggedApi _threeLeggedApi =new ThreeLeggedApi () ;
// Declare a local web listener to wait for the oAuth callback on the local machine.
// Please read this article to configure your local machine properly
// http://stackoverflow.com/questions/4019466/httplistener-access-denied
// ex: netsh http add urlacl url=http://+:3006/oauth user=cyrille
// Embedded webviews are strongly discouraged for oAuth - https://developers.google.com/identity/protocols/OAuth2InstalledApp
private static HttpListener _httpListener =null ;
internal delegate void NewBearerDelegate (dynamic bearer) ;
// For a Synchronous example refer to the 2legged example
// Asynchronous example (recommended)
internal static void _3leggedAsync (NewBearerDelegate cb) {
try {
if ( !HttpListener.IsSupported )
return ; // HttpListener is not supported on this platform.
// Initialize our web listerner
_httpListener =new HttpListener () ;
_httpListener.Prefixes.Add (FORGE_CALLBACK.Replace ("localhost", "+") + "/") ;
_httpListener.Start () ;
IAsyncResult result =_httpListener.BeginGetContext (_3leggedAsyncWaitForCode, cb) ;
// Generate a URL page that asks for permissions for the specified scopes, and call our default web browser.
string oauthUrl =_threeLeggedApi.Authorize (FORGE_CLIENT_ID, oAuthConstants.CODE, FORGE_CALLBACK, _scope) ;
System.Diagnostics.Process.Start (new System.Diagnostics.ProcessStartInfo (oauthUrl)) ;
} catch ( Exception ex ) {
Console.WriteLine (ex.Message) ;
}
}
Once a user receives permissions on the consent page, Forge will redirect the page to the redirect URL you provided when you created the app. An authorization code is returned in the query string.
GET /callback?code={authorizationCode}
internal static async void _3leggedAsyncWaitForCode (IAsyncResult ar) {
try {
// Our local web listener was called back from the Autodesk oAuth server
// That means the user logged properly and granted our application access
// for the requested scope.
// Let's grab the code fron the URL and request or final access_token
//HttpListener listener =(HttpListener)result.AsyncState ;
var context =_httpListener.EndGetContext (ar) ;
string code =context.Request.QueryString [oAuthConstants.CODE] ;
// The code is only to tell the user, he can close is web browser and return
// to this application.
var responseString ="<html><body>You can now close this window!</body></html>" ;
byte[] buffer =Encoding.UTF8.GetBytes (responseString) ;
var response =context.Response ;
response.ContentType ="text/html" ;
response.ContentLength64 =buffer.Length ;
response.StatusCode =200 ;
response.OutputStream.Write (buffer, 0, buffer.Length) ;
response.OutputStream.Close () ;
Request an access token using the authorization code you received, as shown below:
// Now request the final access_token
if ( !string.IsNullOrEmpty (code) ) {
// Call the asynchronous version of the 3-legged client with HTTP information
// HTTP information will help you to verify if the call was successful as well
// as read the HTTP transaction headers.
ApiResponse<dynamic> bearer =await _threeLeggedApi.GettokenAsyncWithHttpInfo (FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, oAuthConstants.AUTHORIZATION_CODE, code, FORGE_CALLBACK) ;
//if ( bearer.StatusCode != 200 )
// throw new Exception ("Request failed! (with HTTP response " + bearer.StatusCode + ")") ;
// The JSON response from the oAuth server is the Data variable and has been
// already parsed into a DynamicDictionary object.
//string token =bearer.Data.token_type + " " + bearer.Data.access_token ;
//DateTime dt =DateTime.Now ;
//dt.AddSeconds (double.Parse (bearer.Data.expires_in.ToString ())) ;
((NewBearerDelegate)ar.AsyncState)?.Invoke (bearer.Data) ;
} else {
((NewBearerDelegate)ar.AsyncState)?.Invoke (null) ;
}
} catch ( Exception ex ) {
Console.WriteLine (ex.Message) ;
((NewBearerDelegate)ar.AsyncState)?.Invoke (null) ;
} finally {
_httpListener.Stop () ;
}
}
private void Window_Initialized (object sender, EventArgs e) {
_3leggedAsync (new NewBearerDelegate (gotit)) ;
}
// This is our application delegate. It is called upon success or failure
// after the process completed
static void gotit (dynamic bearer) {
if ( bearer == null ) {
MessageBox.Show ("Sorry, Authentication failed!", "3legged test", MessageBoxButton.OK, MessageBoxImage.Error) ;
return ;
}
// The call returned successfully and you got a valid access_token.
string token =bearer.token_type + " " + bearer.access_token ;
DateTime dt =DateTime.Now ;
dt.AddSeconds (double.Parse (bearer.expires_in.ToString ())) ;
MessageBox.Show ("You are in!", "3legged test", MessageBoxButton.OK, MessageBoxImage.Information) ;
}
}
}
Note that access tokens expire after a short period of time. The expires_in
field in the bearer
object gives
the validity of an access token in seconds.
To refresh your access token, call the _threeLeggedApi.RefreshtokenAsyncWithHttpInfo()
method.
You can get the full documentation for the API on the Developer Portal
All URIs are relative to https://developer.api.autodesk.com/ (for example createBucket URI is 'https://developer.api.autodesk.com/oss/v2/buckets')
Class | Method | HTTP request | Description |
---|---|---|---|
ActivitiesApi | CreateActivity | POST /autocad.io/us-east/v2/Activities | Creates a new Activity. |
ActivitiesApi | DeleteActivity | DELETE /autocad.io/us-east/v2/Activities('{id}') | Removes a specific Activity. |
ActivitiesApi | DeleteActivityHistory | POST /autocad.io/us-east/v2/Activities('{id}')/Operations.DeleteHistory | Removes the version history of the specified Activity. |
ActivitiesApi | GetActivity | GET /autocad.io/us-east/v2/Activities('{id}') | Returns the details of a specific Activity. |
ActivitiesApi | GetActivityVersions | GET /autocad.io/us-east/v2/Activities('{id}')/Operations.GetVersions | Returns all old versions of a specified Activity. |
ActivitiesApi | GetAllActivities | GET /autocad.io/us-east/v2/Activities | Returns the details of all Activities. |
ActivitiesApi | PatchActivity | PATCH /autocad.io/us-east/v2/Activities('{id}') | Updates an Activity by specifying only the changed attributes. |
ActivitiesApi | SetActivityVersion | POST /autocad.io/us-east/v2/Activities('{id}')/Operations.SetVersion | Sets the Activity to the specified version. |
AppPackagesApi | CreateAppPackage | POST /autocad.io/us-east/v2/AppPackages | Creates an AppPackage module. |
AppPackagesApi | DeleteAppPackage | DELETE /autocad.io/us-east/v2/AppPackages('{id}') | Removes a specific AppPackage. |
AppPackagesApi | DeleteAppPackageHistory | POST /autocad.io/us-east/v2/AppPackages('{id}')/Operations.DeleteHistory | Removes the version history of the specified AppPackage. |
AppPackagesApi | GetAllAppPackages | GET /autocad.io/us-east/v2/AppPackages | Returns the details of all AppPackages. |
AppPackagesApi | GetAppPackage | GET /autocad.io/us-east/v2/AppPackages('{id}') | Returns the details of a specific AppPackage. |
AppPackagesApi | GetAppPackageVersions | GET /autocad.io/us-east/v2/AppPackages('{id}')/Operations.GetVersions | Returns all old versions of a specified AppPackage. |
AppPackagesApi | GetUploadUrl | GET /autocad.io/us-east/v2/AppPackages/Operations.GetUploadUrl | Requests a pre-signed URL for uploading a zip file that contains the binaries for this AppPackage. |
AppPackagesApi | GetUploadUrlWithRequireContentType | GET /autocad.io/us-east/v2/AppPackages/Operations.GetUploadUrl(RequireContentType={require}) | Requests a pre-signed URL for uploading a zip file that contains the binaries for this AppPackage. Unlike the GetUploadUrl method that takes no parameters, this method allows the client to request that the pre-signed URL to be issued so that the subsequent HTTP PUT operation will require Content-Type=binary/octet-stream. |
AppPackagesApi | PatchAppPackage | PATCH /autocad.io/us-east/v2/AppPackages('{id}') | Updates an AppPackage by specifying only the changed attributes. |
AppPackagesApi | SetAppPackageVersion | POST /autocad.io/us-east/v2/AppPackages('{id}')/Operations.SetVersion | Sets the AppPackage to the specified version. |
AppPackagesApi | UpdateAppPackage | PUT /autocad.io/us-east/v2/AppPackages('{id}') | Updates an AppPackage by redefining the entire Activity object. |
BucketsApi | CreateBucket | POST /oss/v2/buckets | |
BucketsApi | DeleteBucket | DELETE /oss/v2/buckets/{bucketKey} | |
BucketsApi | GetBucketDetails | GET /oss/v2/buckets/{bucketKey}/details | |
BucketsApi | GetBuckets | GET /oss/v2/buckets | |
DerivativesApi | DeleteManifest | DELETE /modelderivative/v2/designdata/{urn}/manifest | |
DerivativesApi | GetDerivativeManifest | GET /modelderivative/v2/designdata/{urn}/manifest/{derivativeUrn} | |
DerivativesApi | GetFormats | GET /modelderivative/v2/designdata/formats | |
DerivativesApi | GetManifest | GET /modelderivative/v2/designdata/{urn}/manifest | |
DerivativesApi | GetMetadata | GET /modelderivative/v2/designdata/{urn}/metadata | |
DerivativesApi | GetModelviewMetadata | GET /modelderivative/v2/designdata/{urn}/metadata/{guid} | |
DerivativesApi | GetModelviewProperties | GET /modelderivative/v2/designdata/{urn}/metadata/{guid}/properties | |
DerivativesApi | GetThumbnail | GET /modelderivative/v2/designdata/{urn}/thumbnail | |
DerivativesApi | Translate | POST /modelderivative/v2/designdata/job | |
EnginesApi | GetAllEngines | GET /autocad.io/us-east/v2/Engines | Returns the details of all available AutoCAD core engines. |
EnginesApi | GetEngine | GET /autocad.io/us-east/v2/Engines('{id}') | Returns the details of a specific AutoCAD core engine. |
FoldersApi | GetFolder | GET /data/v1/projects/{project_id}/folders/{folder_id} | |
FoldersApi | GetFolderContents | GET /data/v1/projects/{project_id}/folders/{folder_id}/contents | |
FoldersApi | GetFolderParent | GET /data/v1/projects/{project_id}/folders/{folder_id}/parent | |
FoldersApi | GetFolderRefs | GET /data/v1/projects/{project_id}/folders/{folder_id}/refs | |
FoldersApi | GetFolderRelationshipsRefs | GET /data/v1/projects/{project_id}/folders/{folder_id}/relationships/refs | |
FoldersApi | PostFolderRelationshipsRef | POST /data/v1/projects/{project_id}/folders/{folder_id}/relationships/refs | |
HubsApi | GetHub | GET /project/v1/hubs/{hub_id} | |
HubsApi | GetHubs | GET /project/v1/hubs | |
ItemsApi | GetItem | GET /data/v1/projects/{project_id}/items/{item_id} | |
ItemsApi | GetItemParentFolder | GET /data/v1/projects/{project_id}/items/{item_id}/parent | |
ItemsApi | GetItemRefs | GET /data/v1/projects/{project_id}/items/{item_id}/refs | |
ItemsApi | GetItemRelationshipsRefs | GET /data/v1/projects/{project_id}/items/{item_id}/relationships/refs | |
ItemsApi | GetItemTip | GET /data/v1/projects/{project_id}/items/{item_id}/tip | |
ItemsApi | GetItemVersions | GET /data/v1/projects/{project_id}/items/{item_id}/versions | |
ItemsApi | PostItem | POST /data/v1/projects/{project_id}/items | |
ItemsApi | PostItemRelationshipsRef | POST /data/v1/projects/{project_id}/items/{item_id}/relationships/refs | |
ObjectsApi | CopyTo | PUT /oss/v2/buckets/{bucketKey}/objects/{objectName}/copyto/{newObjName} | |
ObjectsApi | CreateSignedResource | POST /oss/v2/buckets/{bucketKey}/objects/{objectName}/signed | |
ObjectsApi | DeleteObject | DELETE /oss/v2/buckets/{bucketKey}/objects/{objectName} | |
ObjectsApi | DeleteSignedResource | DELETE /oss/v2/signedresources/{id} | |
ObjectsApi | GetObject | GET /oss/v2/buckets/{bucketKey}/objects/{objectName} | |
ObjectsApi | GetObjectDetails | GET /oss/v2/buckets/{bucketKey}/objects/{objectName}/details | |
ObjectsApi | GetObjects | GET /oss/v2/buckets/{bucketKey}/objects | |
ObjectsApi | GetSignedResource | GET /oss/v2/signedresources/{id} | |
ObjectsApi | GetStatusBySessionId | GET /oss/v2/buckets/{bucketKey}/objects/{objectName}/status/{sessionId} | |
ObjectsApi | UploadChunk | PUT /oss/v2/buckets/{bucketKey}/objects/{objectName}/resumable | |
ObjectsApi | UploadObject | PUT /oss/v2/buckets/{bucketKey}/objects/{objectName} | |
ObjectsApi | UploadSignedResource | PUT /oss/v2/signedresources/{id} | |
ObjectsApi | UploadSignedResourcesChunk | PUT /oss/v2/signedresources/{id}/resumable | |
ProjectsApi | GetHubProjects | GET /project/v1/hubs/{hub_id}/projects | |
ProjectsApi | GetProject | GET /project/v1/hubs/{hub_id}/projects/{project_id} | |
ProjectsApi | GetProjectHub | GET /project/v1/hubs/{hub_id}/projects/{project_id}/hub | |
ProjectsApi | PostStorage | POST /data/v1/projects/{project_id}/storage | |
ProjectsApi | PostVersion | POST /data/v1/projects/{project_id}/versions | |
VersionsApi | GetVersion | GET /data/v1/projects/{project_id}/versions/{version_id} | |
VersionsApi | GetVersionItem | GET /data/v1/projects/{project_id}/versions/{version_id}/item | |
VersionsApi | GetVersionRefs | GET /data/v1/projects/{project_id}/versions/{version_id}/refs | |
VersionsApi | GetVersionRelationshipsRefs | GET /data/v1/projects/{project_id}/versions/{version_id}/relationships/refs | |
VersionsApi | PostVersionRelationshipsRef | POST /data/v1/projects/{project_id}/versions/{version_id}/relationships/refs | |
WorkItemsApi | CreateWorkItem | POST /autocad.io/us-east/v2/WorkItems | Creates a new WorkItem. |
WorkItemsApi | DeleteWorkItem | DELETE /autocad.io/us-east/v2/WorkItems('{id}') | Removes a specific WorkItem. |
WorkItemsApi | GetAllWorkItems | GET /autocad.io/us-east/v2/WorkItems | Returns the details of all WorkItems. |
WorkItemsApi | GetWorkItem | GET /autocad.io/us-east/v2/WorkItems('{id}') | Returns the details of a specific WorkItem. |
This sample is licensed under the terms of the [Apache License]. Please see the LICENSE file for full details.