Using NSwag to Generate C# Client Classes for ASP.NET Core 3

This post is going to use one of the tools provided by NSwag to generate C# client classes to provide access to an API. While the NSwag tooling provides multiple ways to discover the definition of an API we will be using the tooling to generate C# classes from an OpenAPI/Swagger specification.

For details on how to use NSwag to provide OpenAPI/Swagger for your APIs check out my Swagger/OpenAPI with NSwag and ASP.NET Core 3 post. You can grab the API I’m using in the post from this GitHub repo if you need an API to play around with. If you do grab the sample API from GitHub not that it does use Entity Framework Core and SQLite which means you will need to create the associated database. Details of how to do that can be found in the Create and Apply Initial Migration section of my ASP.NET Core 3: Add Entity Framework Core to Existing Project post.

Sample Client Application

For this example, we will spin up a Razor Pages application using the .NET CLI with the following command from your favorite terminal application in the directory you want the application created.

dotnet new webapp

NSwag Client Generation

NSwag provides multiple options for client generation including a CLI option, code, and a Windows application. This post is going to use the Windows application which is called NSwagStudio. Download and install NSwagStudio from here.

Next, make sure your API is running and get the URL of its OpenAPI/Swagger specification URL. For example, I am using a local instance of my API and the URL I need is https://localhost:5001/swagger/v1/swagger.json. If you are using the Swagger UI you can find a link to your swagger.json under the API title.

Now that we have the OpenAPI/Swager specification URL for the API we are dealing with open NSwagStudio. The application will open with a new document ready to go. There are a few options we will need to set. First, we want to use the NetCore30 Runtime. Next, select the OpenAPI/Swagger Specification tab and enter your API’s specification URL in the Specification URL box.

In the Outputs section check the CSharp Client checkbox and then select the CSharp Client tab. As you can see from the screenshot below there are a ton of options to tweak. For this example, we are taking the defaults for all of them except for Namespace, which I set to ContactsApi, and Output file path, which is only needed if you use the Generate Files option. Click the Generate Files button and NSwagStudio will create a file that contains all the code needed to access the API described in the OpenAPI/Swager specification selected in the Input section.

Note, the Generate Outputs button can be used if you want to see what the generated code will look in the Output tab on the same level as Settings.

Use Generated Client from the Sample Project

In the sample project, I created an APIs directory and dropped the ContactsApi.cs created with NSwagStudio there. The files generated with NSwagStudio are expecting JSON.NET to be present so the sample project will need a reference to the Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet package.

Now that the project has a reference to JSON.NET in the ConfigureServices function of the Startup class we need to tell the app to make JSON.NET available via dependency injection with the following change.

services.AddRazorPages()
        .AddNewtonsoftJson();

Now to test out the client I used the following OnGet function in the Index.cshtml.cs file.

public async Task OnGet()
{
    using (var httpClient = new HttpClient())
    {
        var contactsClient = new ContactsClient(httpClient);
        var contacts = await contactsClient.GetContactsAsync();
    }
}

Note the above is only meant to show that the generated client work and isn’t meant to be a production-grade example. For more production-grade scenarios make sure and following Microsoft’s guidance on HTTP client usage.

Wrapping Up

NSwag’s client generation seems to be an easy way to get started consuming API’s. I’m not sure if the CLI would provide more options for how the client code is generated or not with support of HTTPClientFactory and strongly typed HTTP Clients. This will be something I may explorer more in a future post.


Also published on Medium.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.