Working with Box OpenAPI Clients

In May of this year, Box announced an OpenAPI specification for their API endpoints.  The specification is available on their Github site, but in implementing it, I found few practical examples and no examples for C#/.NET.

To start with, you will need to get your hands on the swagger code generation tools.  The repository is available on Github, but you’re better off just getting the .jar and be done with it:

Once you’ve got the .jar and the .json files from the Box OpenAPI specification, place them all in the same folder and create another config.json file:

File structure for Box OpenAPI specification and swagger codegen.

The config.json file contains the parameters for the code generator.  You can specify the options at the command line as well, but here is the configuration format:

Note that I’m targeting .NET 3.5.  The packageName  parameter defines the namespace.

Because of the way the swagger codegen tools work, it will generate a bunch of duplicate class names in each of the namespaces.  The easiest way to deal with this is to add a --model-name-prefix  parameter for each of the libraries.

As an example

Once you’ve generated the code, you’ll need to make some minor corrections in the ApiClient  class by replacing the code that attaches the file parameters to the outgoing request:

Without this change, the code will send an empty HTTP request body and no content will be sent.  You will receive the response error (in Fiddler or your HTTP trace tool of choice) of:

Once you’ve got your libraries all ready, you’re good to go.  The problem is that the documentation is somewhat sparse and incomplete.  When you generate the client code, a bunch of samples are also generated under a docs directory in Markdown format.  Here is the example for uploading a file to Box:

The problem is that there is no example of attributes , which is a key property without which the API call will fail.  Fortunately, we can find an example in the online documentation of the API.

Online documentation has an example.

Note that the parent ID should be 0 for the root folder.

Before we can get it all to work, we have to provide an access token and for that, we will need to create an app in Box.  From the developer console, click Create New App.  In this case, I’ll be selecting an Enterprise Integration since I intend to have a standalone service managing the content in a Box tenant.  Once the app is created, there are a few key pieces of information that we will need:

  1. The Enterprise ID on the General page for the app.
  2. The Client ID and Client Secret on the Configuration page for the app.
  3. The Key ID on the Configuration page for the app.

For testing purposes, you can generate a developer token, however, this expires in 60 minutes:

Developer token for initial testing.

For initial testing, this is fine.  However, for the app to work as a service, we will need to use the Token API to create a JWT token to exchange for an access token.  First is to switch the Authentication Model into OAuth 2.0 with JWT (Server Authentication).  Next is to generate a public/private key pair by clicking on Generate a Public/Private Keypair.  Once the key is generated, you’ll have the Key ID that I listed above.

This is where things start to get hairy!  I suppose if you are using .NET 4.6 or .NET Core, your life will be peachy since there are plenty of great libraries on Nuget that you can use to create a JWT token and manage all of this complexity.  For those of us still working on .NET 3.5, you’ll need to do a bit of work before you can generate a token!

First is that we will need to convert the PEM format private key obtained from Box into a format that can be consumed by the .NET RSA crypto provider which wants an XML string.  The best way I found to do this was a piece of code by Michel Gallant.  Paste your private key into a file and run the tool to create a file which will have the key in XML format.  Next we need to create a valid JWT token.  There’s lots of info on the web including the official specification so let’s just take a look at the code:

I’m using ServiceStack.Text to convert the dictionary to JSON.  Bottom line: you don’t really need a fancy library to create a JWT token.  If you have any doubts about the token, use the debugger to check the validity of the token.

Once you have the token, we need to exchange it for an access token using the Token API:

Finally!  You have an access token which can be used to use the API!

This will work fine if you are using it in a console application, but if you try to use it in a web application, you’ll run into two issues.  The first is a cryptic error with a message “The system cannot find the file specified”.  This is an issue with the permissions model of the application pool account configuration which can be fixed by loading the profile for the account.  The second issue is an error message along the lines of “Invalid algorithm specified“.  There are a lot of articles discussing this with various complicated fixes, but I found the easiest fix on a 9 year old Microsoft blog post (Anders Abel has a good explanation if you’re interested).  The solution is to add the following to your web.config:

And with that, you should be able to use the OpenAPI generated clients!  If you log in with your developer account, you won’t find the files under your files; you have to go into the admin console and access the files there under the app:

Admin console where you can find the app folder.

You may also like...