Application Setup
Let's start by creating a new project, installing required dependencies, and setting up a basic server application.
New project
- Node.js & VSCode
- .NET 6 & VSCode
- .NET 6 & VS2022
Create a new folder for your project, navigate to it in the command line, and initialize a new Node.js project:
npm init -y
Next, install all the Node.js dependencies we're going to use. In this case it will be
the Express.js framework, an Express.js middleware
for handling multipart/form-data
requests, and finally the APS SDK:
npm install --save express express-formidable forge-apis
The "dependencies"
in your package.json
file should now look something like this
(potentially with slightly different version numbers):
// ...
"dependencies": {
"express": "^4.17.1",
"express-formidable": "^1.2.0",
"forge-apis": "^0.9.1"
}
// ...
Finally, let's create a couple more subfolders in the project folder that we're going to need later:
wwwroot
- this is where we're going to put all the client side assets (HTML, CSS, JavaScript, images, etc.)routes
- this is where we're going to implement all the server endpointsservices
- here we're going to keep all the server-side logic that can be shared by different endpoints
Now, when you open your project folder in Visual Studio Code for the first time, the folder structure should look similar to this:
Create a new folder for your project, navigate to it in the command line, and initialize a new ASP.NET Core project:
dotnet new web
Next we will need to install the dependencies. In this case it will just be the APS SDK:
dotnet add package Autodesk.Forge
The *.csproj
file in your project should now look similar to this (possibly with
slightly different version numbers, and additional .NET settings):
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autodesk.Forge" Version="1.9.7" />
</ItemGroup>
</Project>
Finally, let's create a couple more subfolders in your project folder that we're going to need later:
Controllers
- this is where we're going to implement all the server endpointsModels
- here we're going to keep all the server-side logic that can be shared by different endpointswwwroot
- this is where we're going to put all the client side assets (HTML, CSS, JavaScript, images, etc.)
Now, when you open your project folder in Visual Studio Code for the first time, you will be prompted
to setup your project for .NET development. Accept the prompt, and the editor will automatically create
a .vscode
subfolder with additional .NET specific settings such as the default launch configuration.
The folder structure in the editor should look similar to this:
If the .vscode
folder is not created automatically, you can create it via the Run & Debug sidepanel
To create the .vscode
folder click on the Run and Debug tool on the left sidepanel > create a launch.json file > Select .NET5+ & .NET Core.
Create a new project in Visual Studio:
Choose the ASP.NET Core Empty template:
Name the project any way you want:
Choose the .NET 6.0 (Long-term support) framework, and disable HTTPS as we don't need it for now:
Once the project is ready, create the following subfolders in your project folder:
Controllers
- this is where we're going to implement all the server endpointsModels
- here we're going to keep all the server-side logic that can be shared by different endpointswwwroot
- this is where we're going to put all the client side assets (HTML, CSS, JavaScript, images, etc.)
Next we will need to install the dependencies. In this case it will just be the APS SDK. In the Solution Explorer, right-click on Dependencies, and then click on Manage NuGet Packages...:
In the NuGet Package Manager, switch to the Browse tab, and search for and install
the Autodesk.Forge
package:
Application config
Our application will need a couple of configuration inputs to run properly, for example, the credentials of our APS app (client ID and secret) for communicating with Autodesk Platform Services, and the name of a bucket in the Data Management service for storing designs. We will pass these parameters to our app using environment variables.
- Node.js & VSCode
- .NET 6 & VSCode
- .NET 6 & VS2022
Create a config.js
file in the root of your project folder, and add the following code:
let { APS_CLIENT_ID, APS_CLIENT_SECRET, APS_BUCKET, PORT } = process.env;
if (!APS_CLIENT_ID || !APS_CLIENT_SECRET) {
console.warn('Missing some of the environment variables.');
process.exit(1);
}
APS_BUCKET = APS_BUCKET || `${APS_CLIENT_ID.toLowerCase()}-basic-app`;
PORT = PORT || 8080;
module.exports = {
APS_CLIENT_ID,
APS_CLIENT_SECRET,
APS_BUCKET,
PORT
};
We simply read the environment variables from process.env
, and exit the application
immediately if any of the required properties are missing. And if no bucket name is provided,
we generate one by appending the -basic-app
suffix to our application Client ID.
Note that the Data Management service requires bucket names to be globally unique,
and attempts to create a bucket with an already used name will fail with 409 Conflict
.
See the documentation
for more details.
Now, to pass actual configuration values to our application for debugging purposes, we need to create
a launch configuration.
Use Run > Add Configuration in the menu to create a new configuration, and when prompted
for the specific environment, choose Node.js. This will create a new .vscode
subfolder in your project with a launch.json
file where you can define different
launch configurations. Replace the content of the file with the following:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Server",
"runtimeExecutable": "npm",
"runtimeArgs": [
"start"
],
"envFile": "${workspaceFolder}/.env",
"skipFiles": [
"<node_internals>/**/*.js"
]
}
]
}
We are defining a single launch configuration called Launch Server that will start
our application (using the npm start
command), and what is more important, it will
look for a .env
file in the project folder, and provide any <key>="<value>"
pairs
defined in this file as environment variables to our application. Let's create
the .env
file in the project folder, and populate it with our environment variables
(using your own values instead of the placeholders of course):
APS_CLIENT_ID="your-client-id"
APS_CLIENT_SECRET="your-client-secret"
APS_BUCKET="optional-name-of-existing-bucket"
Since the .env
file contains sensitive information, make sure that it is not included in git!
This can be ensured by adding the .env
line to the .gitignore file.
Create a Startup.cs
file in the root folder of your project with the following content:
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
var clientID = Configuration["APS_CLIENT_ID"];
var clientSecret = Configuration["APS_CLIENT_SECRET"];
var bucket = Configuration["APS_BUCKET"]; // Optional
if (string.IsNullOrEmpty(clientID) || string.IsNullOrEmpty(clientSecret))
{
throw new ApplicationException("Missing required environment variables APS_CLIENT_ID or APS_CLIENT_SECRET.");
}
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
The Startup
class is responsible for configuring our server and its "middleware", for example,
serving of static files. We also try and retrieve the APS application client ID and secret
from environment variables (or from other configuration providers)
for later use.
Now, to pass actual configuration values to our application for debugging purposes,
we will modify (or create) the appsettings.Development.json
file in our project folder,
or create one of it does not exist, with the following content (using your own
values instead of the placeholders of course):
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"APS_CLIENT_ID": "your-client-id",
"APS_CLIENT_SECRET": "your-client-secret",
"APS_BUCKET": "optional-name-of-existing-bucket"
}
Since the appsettings.Development.json
file contains sensitive information, make sure that it is not included in git!
This can be ensured by adding the appsettings.Development.json
line to the .gitignore file.
Create a Startup.cs
file in the root folder of your project with the following content:
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
var clientID = Configuration["APS_CLIENT_ID"];
var clientSecret = Configuration["APS_CLIENT_SECRET"];
var bucket = Configuration["APS_BUCKET"]; // Optional
if (string.IsNullOrEmpty(clientID) || string.IsNullOrEmpty(clientSecret))
{
throw new ApplicationException("Missing required environment variables APS_CLIENT_ID or APS_CLIENT_SECRET.");
}
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
The Startup
class is responsible for configuring our server and its "middleware", for example,
serving of static files. We also try and retrieve the APS application client ID and secret
from environment variables (or from other configuration providers)
for later use.
Now, to pass actual configuration values to our application for debugging purposes,
we will modify (or create) the appsettings.Development.json
file in our project folder,
or create one of it does not exist, with the following content (using your own
values instead of the placeholders of course):
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"APS_CLIENT_ID": "your-client-id",
"APS_CLIENT_SECRET": "your-client-secret",
"APS_BUCKET": "optional-name-of-existing-bucket"
}
Since the appsettings.Development.json
file contains sensitive information, make sure that it is not included in git!
This can be ensured by adding the appsettings.Development.json
line to the .gitignore file.
Basic server
Next we'll create a basic server application.
- Node.js & VSCode
- .NET 6 & VSCode
- .NET 6 & VS2022
Create a server.js
file in the root of your project folder with the following code:
const express = require('express');
const { PORT } = require('./config.js');
let app = express();
app.use(express.static('wwwroot'));
app.listen(PORT, function () { console.log(`Server listening on port ${PORT}...`); });
For now the server isn't doing much, just serving static assets from the wwwroot
subfolder
(which is currently empty), and reporting any errors to the console and back to the client.
Next, let's add a "start": "node server.js"
script to the package.json
file so that we can
easily run our application later:
// ...
"scripts": {
"start": "node server.js"
}
// ...
Replace the content of Program.cs
with the following:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
With this code our .NET application will start an ASP.NET server with the configuration
defined in the Startup
class.
And finally, let's update the launchSettings.json
file under the Properties
folder to make
sure that our server app is using the default protocol (HTTP) and port (8080) that we
will use throughout this tutorial. Update the applicationUrl
property of the default
launch profile to http://localhost:8080
:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:38524",
"sslPort": 44323
}
},
"profiles": {
"my_aps_app": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:8080",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Replace the content of Program.cs
with the following:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
With this code our .NET application will start an ASP.NET server with the configuration
defined in the Startup
class.
And finally, let's update the launchSettings.json
file under the Properties
folder to make
sure that our server app is using the default protocol (HTTP) and port (8080) that we
will use throughout this tutorial. Update the applicationUrl
property of the default
launch profile to http://localhost:8080
:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:38524",
"sslPort": 44323
}
},
"profiles": {
"MyApsApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:8080",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Try it out
Now that we have a basic application setup, let's try it out!
- Node.js & VSCode
- .NET 6 & VSCode
- .NET 6 & VS2022
Start the application from Visual Studio Code (for example, via the Run > Start Debugging
menu, or by pressing F5
), and navigate to http://localhost:8080
in the browser. The server should respond with Cannot GET /
because we haven't added any
logic to it just yet. That's going to be the topic of the next step.
Start the application from Visual Studio Code (for example, via the Run > Start Debugging
menu, or by pressing F5
), and navigate to http://localhost:8080
in the browser. You should get a 404 response because we haven't implemented any server logic yet.
That's going to be the goal of the next step.
Start the application from Visual Studio (for example, via the Debug > Start Debugging
menu, or by pressing F5
), and it will automatically open http://localhost:8080
in your browser. You should get a 404 response because we haven't implemented any server logic yet.
That's going to be the goal of the next step.