Using NSwag to Generate Blazor Server Client for an ASP.NET Core 3.1 API

This week we are going to add a Blazor Server project that will utilize the contacts API we created a few weeks ago. This post is part of the revamp of the ASP.NET Core Basics repo that was kicked off when .NET Core 3.0 was released. For details on how the associated sample got to the current point in the application check out the following posts.

Swagger/OpenAPI with NSwag and ASP.NET Core 3
ASP.NET Core 3: Add Entity Framework Core to Existing Project
New Razor Pages Project Backed with an API
Using NSwag to Generate Angular Client for an ASP.NET Core 3 API
Using NSwag to Generate React Client for an ASP.NET Core 3 API
Using NSwag to Generate Blazor Server Client for an ASP.NET Core 3.1 API
Using NSwag to Generate a Vue Client for an ASP.NET Core 3.1 API

The sample code before any of the changes in this post can be found here.

Create the Blazor Server Project

Add a new directory for the Blazor Server project and then open a terminal set to that directory. The following command can be used to create a new Blazor Server project.

dotnet new blazorserver

Next, use the following command to add the new project to the solution file which is in the root of the repo. Your filenames and paths will vary of course.

dotnet sln ..\..\BasicsRefresh.sln add ContactsBlazorServerApp.csproj

Using NSwageStudio to Generate an API Client

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 switch over to 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. For this example, we are taking the defaults for all of the options except for Namespace, which is set to ContactsApi, Generate interfaces for Client classes, which should be check, 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.

The Generate Outputs button can be used if to populate the Output tab with the same code that the Generate Files process creates which provides a nice way to play with settings to and see the output without having to open another file.

Setting Up the Generated Client in the Blazor Server Project

In the sample project, create 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.

With the client-generated and in our local Apis directory in the Razor Pages project we can now work on getting it configured and registered for use in our new project. First, open the apppsetting.json file and add a setting for the URL of our API, which is the ContactsApi value in the following sample.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ContactsApi": "https://localhost:5001"
}

Now that the project has the configuration change and 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 by using AddNewtonsoftJson as in the following example.

services.AddRazorPages()
        .AddNewtonsoftJson();

Also in the ConfigureServices function, we need to register our API client.

services.AddHttpClient<IContactsClient, 
                       ContactsClient>(client => 
         client.BaseAddress = new Uri(Configuration.GetSection("ContactsApi").Value));

Create the UI and Usage of the Generated Client

Now that all the setup work is done we can add the contact list UI which will show the usage of the API client. The following is the full code which for the sample is in a new ContactList.razor file in the Pages directory. The specific lines related to the API client are highlighted.

@page "/contactlist"

@using Apis
@inject IContactsClient ContactClient

<h1>Contact List</h1>

@if (_contacts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table className='table table-striped' aria-labelledby="tabelLabel">
        <thead>
            <tr>
                <th>Name</th>
                <th>Address</th>
                <th>City</th>
                <th>State</th>
                <th>Postal Code</th>
                <th>Phone</th>
                <th>Email</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var contact in _contacts)
            {
                <tr>
                    <td>@contact.Name</td>
                    <td>@contact.Address</td>
                    <td>@contact.City</td>
                    <td>@contact.State</td>
                    <td>@contact.PostalCode</td>
                    <td>@contact.Phone</td>
                    <td>@contact.Email</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private ICollection<Contact> _contacts;

    protected override async Task OnInitializedAsync()
    {
        _contacts = await ContactClient.GetContactsAsync();
    }
}

Finally to add our new page to the navbar open the NavMenu.razor file found in the Shared directory. Add the following list item to the unordered list.

<li class="nav-item px-3">
    <NavLink class="nav-link" href="contactlist">
        <span class="oi oi-list" aria-hidden="true"></span> Contacts
    </NavLink>
</li>

Wrapping Up

As with the other posts I have been doing utilizing NSwag for client generation this process is pretty easy and simplifies API consumption.

The sample code in its final state can be found here.


Also published on Medium.

Leave a Comment

Your email address will not be published.

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