Tool Spotlight

Don’t Launch a Browser Running ASP.NET Core Back-end Created from Web Template Studio

In last week’s post, I mentioned off-hand that we could stop VSCode from launching a web browser when starting a debug session on the back-end of our application. This is going to be a quick post on how to stop that browser launch.  The following are the previous Web Template Studio related posts if you want to catch up.

Create an Application with Web Template Studio
Debug ASP.NET Core Back-end Created from Web Template Studio

 

Launch Configurations

If you recall from last week to run our back-end we used the debug tab in VSCode and then hit the Run button for the .NET Core Launch (web) configuration.

The options that are available for running in VSCode are controlled by a launch.json file found in the .vscode directory. The following screenshot is the launch.json for the sample project from last week.

Stop the Browser

To stop the browser from opening delete the serverReadyAction section in the specific configuration you are dealing with. From the sample in the screenshot above the following is what would be removed from the  .NET Core Launch (web) configuration.

// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
    "action": "openExternally",
    "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},

With the above removed hitting the run button for this configuration will no longer launch a browser, but the rest of the debugging experience will remain as it was before.

Wrapping Up

Hopefully, this will help remove a little annoyance in the development. For more details on the serverReadyAction check out the docs. I also recommend checking out the full docs for launch.json to get a good feel of what all is possible.

Don’t Launch a Browser Running ASP.NET Core Back-end Created from Web Template Studio Read More »

Debug ASP.NET Core Back-end Created from Web Template Studio

Last week we covered how to Create an Application with Web Template Studio and now that we have an application we are going to work through how to debug the ASP.NET Core back-end.

Sample Application

The sample application used in this post has been expanded from what we used last week to include two instances of each page type provided by Web Template Studio. The gird, list, and master/detail page types trigger controllers to be added to our back-end application which will give us something to work with. To add these extra page types you have to run through the full wizard in Web Template Studio and not use the create project button on the first page of the wizard. The following is a screenshot of the new sample application with the extra page types.

Debugging in VSCode

Our goal in this post is going to be to hit a breakpoint in the controller action that returns the data for the gird page in the screenshot above. Looking through the project under server/Controllers it looks pretty likely that we are interested in the GridController. This controller only has one action so click to the left of the line number for the line that has the return statement for the Get function.

Unlike the post from last week to debug the back-end we need to run it separate from the front-end which means we need to move away from using npm start to run the whole application. Use the following command to start just the front-end.

npm start-frontend

Now to run the back-end goto the Run section in VSCode and then click the Play button to run the back-end using the .NET Core Launch (web) profile.

This will launch a blank page which we don’t need and it can be closed. If the blank page bothers you too much it can be changed in the launch profile. Now that our back-end is running use the front-end to navigate to the Grid page.

Wrapping Up

Hopefully, with the above steps, you are ready to debug the back-end part of your application. I’m betting for most of us running the front-end and back-end separately is going to more closely match how we normally work. For more information on debugging in VSCode check out the official doc.

Debug ASP.NET Core Back-end Created from Web Template Studio Read More »

Create an Application with Web Template Studio

Creating new applications is something I do a fair amount of. Most of the time they are throwaway projects used to test something out or demo projects used for this blog. With all the project creation going on I try and keep an eye out for tools that make the process easier. This post is going to cover a tool a came across a few weeks ago from Microsoft call Web Template Studio (WebTS).

What is WebTS?

From the project’s GitHub read me:

Microsoft Web Template Studio (WebTS) is a Visual Studio Code Extension that accelerates the creation of new web applications using a wizard-based experience. WebTS enables developers to generate boilerplate code for a web application by choosing between different front-end frameworks, back-end frameworks, pages and cloud services. The resulting web app is well-formed, readable code that incorporates cloud services on Azure while implementing proven patterns and best practices.

For the front-end, we have options of Angular, React, or Vue and on the back-end, there are options for ASP.NET Core, Flask, Molecular, or Node.

Installation

We are assuming you already have a recent version of Visual Studio Code (VSCode) installed, but if not you can download it from here. Open VSCode and from the left side of the screen select Extensions. In the search box at the top enter Web Template Studio and then from the list select Web Template Studio. In the detail page that opens click the green Install button at the top.

Project Creation

Now that we have the extension installed press Ctrl + Shift + P to open the VSCode command palette and enter Web Template Studio: Launch (or as much as needed for the option to show) and then select Web Template Studio: Launch.

This will launch the Web Template Studio project creation process. The first page that shows gives you a very basic set of options, but enough for our example. To see the full array of options Web Template Studio provides hit next on this first screen instead of Create Project like we do in this example. Also, note that if you want an ASP.NET [Core] back-end you need to select it on this summary screen as it isn’t yet an option later in the process. Back to our example, on this page, you will need to enter a Project Name, pick a Front-end Framework, and a Back-end Framework before finally clicking Create Project.

After the process finishes a dialog will show letting us know it is complete. Click Open Project to load the created project in a new instance of VSCode.

Running the Project

Before getting to a runnable state we need to run a couple of terminal commands first. This can be done from VSCode’s built-in terminal or from an external terminal of your choice. In VSCode if you don’t see a terminal you can use Cntrl + Shift + ` to open a new one, or from the menu select Terminal > New Terminal. The following are the two commands that need to be run using npm, but they can be adjusted to use yarn instead if you prefer it. The second command may be specific to an ASP.NET Core back-end, make sure and check the project README.md for verification.

npm install
npm run restore-packages

Now the project can be run with the following command.

npm start

The resulting application will look something like this.

Wrapping Up

WebTS seems to be a great tool for quickly getting a project up and running. I do recommend going through the full project creation wizard as it has options to set up Azure integration as well as the ability to add up to 20 different pages to the generated application. Also, keep in mind that the ASP.NET back-end framework option is pretty new so I wouldn’t be surprised to see some changes as it progresses through the preview stage. Make sure and check out the project’s GitHub repo.

Create an Application with Web Template Studio Read More »

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

This week we are going to add an Aurelia project that will utilize the contacts API we created a few weeks ago using a client-generated by NSwag. 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 which is now targeting .NET Core 3.1. For details on how the associated samples got to their current point 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 changes from this post can be found here.


 

Create the Aurelia Project

As with Vue there is no .NET CLI template from Microsoft that has Aurelia support so to crate the Aurelia project we will be using the Aurelia CLI. Before getting started ensure you have npm installed.

Install the Aurelia CLI using the following command from a command prompt.

npm install -g aurelia-cli

Next, use the following command to start the project creation process using the Aurelia CLI. Keep in mind that the CLI creates a directory with the project name.

au new

The above will result in a walkthrough of the project creation process. First is the name of the project, contacts-aurelia in this case. Next is the setup of the project and here we will be using the Default TypeScript App.

Finally, select how you would like to manage dependencies. The sample project is using npm, but Yarn is also an option. If you do go with Yarn some of the following steps will need the npm commands translated to Yarn commands.

After the project creation process is complete use the following command to change to the new directory created for the project.

cd contacts-aurelia

Now the project needs a few more dependencies installed. We are going to install a couple of UI related items, Bootstrap and Font Awesome, as well as the Aurelia Fetch Client which we will need to hit our API.

npm install bootstrap
npm install font-awesome
npm install aurelia-fetch-client

The application that the Aurelia CLI outputs is very basics so the Aurelia docs for creating a to-do application and creating a contact manager were used to build the basics of the sample application. I will be coving the contact related bits of the UI, but the application stops short of implementing the save functionality at this point.

Use NSwagStudio to Generate an API Client

NSwag provides multiple options for client generation including a CLI, code, or a Windows application. This post is going to use the Windows application which is called NSwagStudio. NSwagStudio can be downloaded and installed from here.

Next, make sure your API is running and get the URL of its OpenAPI/Swagger specification URL. For example, using a local instance of the sample solution’s Contacts API the URL 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, select the OpenAPI/Swagger Specification tab and enter your API’s specification URL in the Specification URL box.

In the Outputs section check the TypeScript Client checkbox and then select the TypeScript Client tab. There are a lot of options to play with, the highlighted options are the ones that are important for this sample. For Template, we just need an Aurelia based client. The final option that needs to be set is the Output file path and this is the location you want the generated file to be. I output to the Aurelia project directory under /src/contactApi.ts. After all the options are set click Generate Files.

Create UI and Use Generated Client

Again the UI bit mostly comes from the docs, but I’m going to show the bits for the contact list here and the rest of the UI you can look at the sample code. All of the following will be taking place in the src directory of the Aurelia project.

First, add a file named contact-list.html which will hold the template for the UI of the contact list with the following contents. This is a mix of HTML and Aurelia’s syntax. We aren’t really going into the Aurelia specific bits, but even if you are new to Aurelia this should be readable.

<template>
  <div class="contact-list">
    <ul class="list-group">
      <li repeat.for="contact of contacts" class="list-group-item ${contact.id === $parent.selectedId ? 'active' : ''}">
        <a route-href="route: contacts; params.bind: {id:contact.id}" click.delegate="$parent.select(contact)">
          <h4>${contact.firstName} ${contact.lastName}</h4>
          <p>${contact.email}</p>
        </a>
      </li>
    </ul>
  </div>
</template>

Next, add a contact-list.ts file which is what the template from above will be bound to. The lines specific to the usage of the NSwag generated client are highlighted.

import {ContactsClient, Contact} from './contactsApi';
import {inject} from 'aurelia-framework';

@inject(ContactsClient)
export class ContactList {
  contacts: Contact[];
  api: ContactsClient;
  selectedId: any;
  
  constructor(api: ContactsClient) {
    this.api = api;
    this.contacts = [];
  }

  created() {
    this.api.getContacts().then(contacts => this.contacts = contacts);
  }

  select(contact) {
    this.selectedId = contact.id;
    return true;
  }
}

As you can see from the above Aurelia is injecting an instance of the ContactsClient via the class’s construction and then that client is used in the created function to call the API client’s getContacts function and using the resulting data from the API to replace the contacts field with the results of the API call.

The application is displaying the contact list in app.html via the contact-list element. The import and usage of the contact list component are highlighted in the following chunk of code.

<template>
  <require from="./styles.css"></require>
  <require from="./contact-list"></require>

  <nav class="navbar navbar-light bg-light fixed-top" role="navigation">
    <a class="navbar-brand" href="#">
      <i class="fa fa-user"></i>
      <span>Contacts</span>
    </a>
  </nav>

  <div class="container">
    <div class="row">
      <contact-list class="col-md-4"></contact-list>
      <router-view class="col-md-8"></router-view>
    </div>
  </div>
</template>

At this point, I tried out the application and it wasn’t pulling back any data. After doing some digging in the network tab of my browser’s dev tool I noticed that the API call was missing the base part of the URL. This hasn’t come up before for the other times I have used the NSwag generated client and if you look at the constructor of the client it defaults the base URL to the endpoint that was used to generate the client, see the following code.

constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
    this.http = http ? http : <any>window;
    this.baseUrl = baseUrl ? baseUrl : "https://localhost:5001";
}

It turns out that the Aurelia dependency injection system calls the constructor with an empty string instead of null. One option would have been to change the above constructor to handle an empty string, but that would mean any time the client got regenerated I would have to remember to follow it up with the constructor modification which would be too easy to screw up. After some digging, I found out that Aurelia provides a way to control how an instance of a class is created. Open main.ts and make the following highlighted changes. I’m injecting the URL, but using null instead would also work and the base URL from the ContactClient would get used.

import { HttpClient } from 'aurelia-fetch-client';
import {Aurelia} from 'aurelia-framework'
import * as environment from '../config/environment.json';
import {PLATFORM} from 'aurelia-pal';
import 'bootstrap/dist/css/bootstrap.css';
import 'font-awesome/css/font-awesome.css';
import { ContactsClient } from 'contactsApi';

export function configure(aurelia: Aurelia) {
  aurelia.use
    .standardConfiguration()
    .feature(PLATFORM.moduleName('resources/index'))
    .instance(ContactsClient, 
              new ContactsClient("https://localhost:5001",
                                 aurelia.container.get(HttpClient)));

  aurelia.use.developmentLogging(environment.debug ? 'debug' : 'warn');

  if (environment.testing) {
    aurelia.use.plugin(PLATFORM.moduleName('aurelia-testing'));
  }

  aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));
}

After all the change from a command prompt set to the root of the Aurelia project, you can use the following command to run the application. If you drop the open it will run the application without opening a browser.

au run --open

Wrapping Up

As always NSwag makes it very easy to create a client to interact with an API. Hopefully, this was useful even if my Aurelia code might not be idiomatic.

The sample projects after all the changes in this post can be found here.

Using NSwag to Generate an Aurelia Client for an ASP.NET Core 3.1 API Read More »

Using NSwag to Generate a Vue Client for an ASP.NET Core 3.1 API

This week we are going to add a Vue project that will utilize the contacts API we created a few weeks ago using a client-generated by NSwag. 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 which is now targeting .NET Core 3.1. For details on how the associated samples got to their current point 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 changes from this post can be found here.

Create the Vue Project

Unlike the rest of the projects in this series, there is no .NET CLI template from Microsoft that has Vue support so to crate the Vue project we will be using the Vue CLI. Before getting started ensure you have npm installed.

Install the Vue CLI using the following command from a command prompt.

npm install -g @vue/cli

Next, use the following command to start the project creation process using the Vue CLI. Keep in mind that the CLI creates a directory with the project name.

vue create contacts-vue

The above command kicks off a series of questions about the application. This sample is going to use TypeScript which means that the default can’t be used so we need to select Manually select features.

For the next question, we need to select TypeScript. I also included the Router and Linter / Formatter. I also found out later in the process that Babel was needed so feel free to select it on this question.

The project creation process asked a bunch more questions that I basically took the defaults on. Here is a screenshot of all the questions and the options I used.

Now that the project is created if we need to change directories to the one created in the above process.

cd contacts-vue

Use the following command to run the new project.

npm run serve

Use NSwagStudio to Generate an API Client

NSwag provides multiple options for client generation including a CLI, code, or a Windows application. This post is going to use the Windows application which is called NSwagStudio. NSwagStudio can be downloaded and installed from here.

Next, make sure your API is running and get the URL of its OpenAPI/Swagger specification URL. For example, using a local instance of the sample solution’s Contacts API the URL 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, select the OpenAPI/Swagger Specification tab and enter your API’s specification URL in the Specification URL box.

In the Outputs section check the TypeScript Client checkbox and then select the TypeScript Client tab. There are a lot of options to play with, the highlighted options are the ones that are important for this sample. First, make sure Module name and Namespace are both empty. I’m sure there is a way to get the client working with a module or namespace, but I didn’t have any luck.   For Template, we just need a Fetch based client. The final option that needs to be set is the Output file path and this is the location you want the generated file to be. I output to the Vue project directory under /src/apis/contactApi.ts. After all the options are set click Generate Files.

Create UI and Use Generated Client

Note that I haven’t touch Vue in a long time so the actually UI bits may or may not be the “proper” way to do this stuff in Vue, but it should be understandable enough that you can see how the API client is used. As with the other post in this same vein, we are going to create a contact list that gets its data from an API.

First, we are going to create a new component for the contact list in the /src/component directory with the filename of ContactList.vue with the following contents. The lines specific to the usage of the NSwag generated client are highlighted.

<template>
  <div>
    <table class="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>
        <tr v-for="contact in contacts" v-bind:key="contact.id">
          <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>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import { ContactsClient, Contact } from '../apis/contactsApi'
@Component
export default class HelloWorld extends Vue {
  name: string = 'ContactList';
  contacts: Contact[] = [];
  private created () {
    let client = new ContactsClient()
    client.getContacts().then(data => (this.contacts = data))
  }
}
</script>

<style scoped>
</style>

As you can see from the created function above we are creating a new instance of the ContactsClient and calling its getContacts function and using the data we get back from the API to replace the contacts field with the results of the API call.

Next, we are going to create a ContactList.vue under the /src/views directory with the following code. This is basically a wrapper around the component we created above.

<template>
  <div>
    <ContactListComponent/>
  </div>
</template>

<script>
import ContactListComponent from '@/components/ContacList'
export default {
  name: 'contactList',
  components: {
    ContactListComponent
  }
}
</script>

Now that we have our view ready we need to add a link to the application’s navigation so a user can get to the contact list. Open App.vue and a router link to the nav div for the contact list.

<div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link to="/contactList">Contacts</router-link> |
    <router-link to="/about">About</router-link>
</div>

Now we need to add the new component to the routes for the application. Open index.ts in the /src/router directory and add an import for the contact list view.

import ContactList from '../views/ContactList.vue'

Finally, add the contact list to the routes array.

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  {
    path: '/contactList',
    name: 'contactList',
    component: ContactList
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

Wrapping Up

As always NSwag makes it very easy to create a client to interact with an API. Hopefully, this was useful even if my Vue code might not be idiomatic.

The sample projects after all the changes in this post can be found here.

Using NSwag to Generate a Vue Client for an ASP.NET Core 3.1 API Read More »

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.

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

Using NSwag to Generate React Client for an ASP.NET Core 3 API

This week we are going to add a React 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

I realize that using an ASP.NET Core backed React project for this sample is overkill and a raw React application would have been all that is needed. I chose to use the ASP.NET Core template as a base for all the projects in this series to be consistent. After the initial application creation, you can think of this example as setting up access to a secondary API in addition to the application’s main API if that helps or the generated client on the React side could be used to wrap the API generated by the template.

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

Create the React Project

Add a new directory for the React project and then open a terminal set to that directory. The following command can be used to create a new React project. The target framework isn’t required, but I have a preview of .NET Core 3.1 installed and I wanted to make sure this project is targeting .NET Core 3.0.

dotnet new react -f netcoreapp3.0

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 if you are not using the sample code of course.

dotnet sln ..\..\BasicsRefresh.sln add ContactsReact.csproj

Use NSwagStudio to Generate React Client

NSwag provides multiple options for client generation including a CLI, 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, select the OpenAPI/Swagger Specification tab and enter your API’s specification URL in the Specification URL box.

In the Outputs section check the TypeScript Client checkbox and then select the TypeScript Client tab. There are a lot of options to play with, but I highlighted the options that were important for this sample. First, make sure Module name and Namespace are both empty. I’m sure there is a way to get the client working with a module or namespace, but I didn’t have any luck.   For Template, we just need a Fetch based client. The final option that needs to be set is the Output file path and this is the location you want the generated file to be. I output to the React project directory under ClientApp\src\app\components\contactApi.ts. After all the options are set click Generate Files.

Create UI and Use Generated Client

Once the above is done once you switch back to Visual Studio you should see the following prompt to add the Microsoft.TypeScript.MSBuild NuGet package. The React template doesn’t use TypeScript and NSwag doesn’t have an option to generate a plain JavaScript client so adding this package will allow the build process to take our TypeScript client and convert it to JavaScript. There is an open issue requesting a JavaScript generator.

The sample API is for contact management so the UI we are going to build is to display a contact list. In the ClientApp/src/component directory add a new file named ContactList.js with the following contents. The lines specific to the usage of the NSwag generated client are highlighted.

import React, { Component } from 'react';
import { ContactsClient } from './contactsApi';  

export class ContactList extends Component {
    static displayName = ContactList.name;

    constructor(props) {
        super(props);
        this.state = { contacts: [], loading: true };
    }

    componentDidMount() {
        this.populateContactData();
    }

    static renderContactsTable(contacts) {
        return (
            <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>
                    {contacts.map(contact =>
                        <tr key={contact.id}>
                            <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>
        );
    }

    render() {
        let contents = this.state.loading
            ? <p><em>Loading...</em></p>
            : ContactList.renderContactsTable(this.state.contacts);

        return (
            <div>
                <h1 id="tabelLabel" >Contacts</h1>
                {contents}
            </div>
        );
    }

    async populateContactData() {
        let client = new ContactsClient();
        client.getContacts()
              .then(data => this.setState({ contacts: data, loading: false }));
    }
}

As you can see from the populateContactData code above we are creating a new instance of the ContactsClient and calling its getContacts function and using the data we get back from the API to set the state of the component with the data return from the API.

Now that the contact list is ready it needs a link in the navbar. First, in the App.js file, we need to add the contact list to the router. The following is the full file with the added lines highlighted.

import React, { Component } from 'react';
import { Route } from 'react-router';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';
import { ContactList } from './components/ContactList';

import './custom.css'

export default class App extends Component {
  static displayName = App.name;

  render () {
    return (
      <Layout>
        <Route exact path='/' component={Home} />
        <Route path='/contacts' component={ContactList} />
        <Route path='/counter' component={Counter} />
        <Route path='/fetch-data' component={FetchData} />
      </Layout>
    );
  }
}

Now to make to add a Contacts link to the navbar open the NavMenu.js file and add the following to the with the other nav items.

<NavItem>
    <NavLink tag={Link} className="text-dark" to="/contacts">Contacts</NavLink>
</NavItem>

Wrapping  Up

I had a bit more trouble getting the NSwag client working this round, but that was more due to my shallow knowledge with React than a problem with NSwag.

The sample projects after all the changes in this post can be found here.

Using NSwag to Generate React Client for an ASP.NET Core 3 API Read More »

Using NSwag to Generate Angular Client for an ASP.NET Core 3 API

This week we are going to add an Angular project that will utilize the API we created a few weeks ago. This post is part of the revamp of my ASP.NET Core Basics repo that I kicked off when .NET Core 3.0 was released. For details on how we 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

Do note that I realize that using an ASP.NET Core backed Angular project for this sample is overkill and a plain Angular application would have been all that is needed, but I wanted to use the ASP.NET Core template as a base for all the projects in this series. After the initial application creation, you can think of this example as setting up access to a secondary API in addition to the application’s main API if that helps.

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

API Changes

Before we get to the actual Angular side of this post we are going to update the associated API to accept all cross-origin resource sharing (CORS) requests. The ASP.NET Core setup has a lot of options and I recommend being me explicit about what your API will accept if you can. Check out the official Microsoft CORS docs for more information.

All the changes needed will be in the Startup class of the API project. The CORS setup is policy-based and each policy needs a name that I stored in the following class level constant.

private const string AllowAllCors = "AllowAll";

In the ConfigureServices function add the following to register the CORS policy. Again be more restrictive with your policy if you can but for this example, we are opening up the API to allow any request.

services.AddCors(options =>
                 {
                     options.AddPolicy(AllowAllCors,
                                       builder =>
                                       {
                                           builder.AllowAnyHeader();
                                           builder.AllowAnyMethod();
                                           builder.AllowAnyOrigin();
                                       });
                 });

Finally, in the Configure function add the following to get CORS added to the HTTP pipeline processing. I’m not 100% sure if it matters where you added it in the pipeline, but I added it close to the front. I included a bit pipeline in the sample app for reference.

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseCors(AllowAllCors);

app.UseHttpsRedirection();

That is all the changes needed for the API, next we will create a new Angular project.

Create an Angular Project

Add a new directory for the application and then in a terminal navigate to that directory. Then the following command can be used to create the new Angular project. The target framework isn’t required, but I have a preview of .NET Core 3.1 installed and I wanted to make sure this project is targeting .NET Core 3.0.

dotnet new angular -f netcoreapp3.0

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 could vary if you can’t using the same code of course.

dotnet sln ..\..\BasicsRefresh.sln add ContactsAngular.csproj

Use NSwagStudio to Generate Angular 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, select the OpenAPI/Swagger Specification tab and enter your API’s specification URL in the Specification URL box.

In the Outputs section check the TypeScript Client checkbox and then select the TypeScript Client tab. There are a lot of options to play with, but I highlighted the ones I changed to generate the client for this sample. First I entered a Module name so the generated code will all be in that module. For Template, it is very important to select Angular so that the resulting code will be set up for Angular’s dependency injection. Also, make sure and change the Injection token type to InjectionToken if you are on a newer version of Angular. The final option that needs to be set is the Output file path and this is the location you want the generated file to be. I output the Angular project directory under ClientApp\src\app\apis\contactApi.ts. After all the options are set click Generate Files.

For more information on generating Angular clients check the official docs on the subject.

Create UI and Use Generated Client

The sample API is for contact management so the UI we are going to build is to display a contact list. The new components are going to go in a new contacts directory under ClientApp\src\app. In this directory, we will need two new files one for the HTML, contact-list.component.html, and the other for the backing TypeScript class, contact-list.component.ts.

The following is the full content on the HTML file. I’m not going to go into the Angular specific bit in this post, but even if you don’t know Angular you will get the idea of what is going on. The rendered result will be a table of contacts.

<h1 id="tableLabel">Contacts</h1>

<p *ngIf="!contacts"><em>Loading...</em></p>

<table class='table table-striped' aria-labelledby="tableLabel" *ngIf="contacts">
  <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>
    <tr *ngFor="let contact of contacts">
      <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>

Next is the TypeScript class for the contact list. This is where you get to see the usage of the client that NSwag generated. The related lines are highlighted.

import { Component } from '@angular/core';
import { contacts as Contacts } from "../apis/contactApi";

@Component({
  selector: 'app-contact-list',
  templateUrl: './contact-list.component.html'
})
export class ContactListComponent {
  public contacts: Contacts.IContact[];

  constructor(contactsClient : Contacts.ContactsClient) {
    contactsClient.getContacts().subscribe(result => {
        this.contacts = result;
      },
      error => console.error(error));
  }
}

As you can see from the code above we are injecting the ContactClient and then calling its getContracts and assigning the results to the class’s local contacts variable.

Now that our components are built we need to register them with the application. These changes are in the app.module.ts file found in the ClientApp\src\app directory. The following is the full file excluding the imports that were existing with the changes for our contact related items highlighted.

import { ContactListComponent } from "./contacts/contact-list.component";
import { contacts } from "./apis/contactApi";

@NgModule({
  declarations: [
    AppComponent,
    NavMenuComponent,
    HomeComponent,
    CounterComponent,
    FetchDataComponent,
    ContactListComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
    HttpClientModule,
    FormsModule, 
    RouterModule.forRoot([
      { path: '', component: HomeComponent, pathMatch: 'full' },
      { path: 'contact-list', component: ContactListComponent },
      { path: 'counter', component: CounterComponent },
      { path: 'fetch-data', component: FetchDataComponent },
    ])
  ],
  providers: [contacts.ContactsClient],
  bootstrap: [AppComponent]
})
export class AppModule { }

The first change was to import both the ContactListComponent and contacts which is the contact client. Next, the ContactListComponent was added to the declarations array. Then we added the ContactListComponent to the RouterModule so that Angular will know how to get us to the contact list page. Finally, we added the ContractsClient to the providers array which will allow Angular to inject the client into our contact list component.

To add our contact list to the nav menu we need to change the nav-menu.component.html file in the ClientApp\src\app\nav-menu directory. Add the following list item to add a Contact link in the navbar.

<li class="nav-item" [routerLinkActive]="['link-active']">
  <a class="nav-link text-dark" [routerLink]="['/contact-list']"
    >Contacts</a
  >
</li>

Wrapping Up

I’m repeating myself, but NSwag’s client generation makes it very simple to get starting consuming APIs, but even over time being able to regenerate a client for an API and have any changes in that API ready to go is really nice.

The sample projects after all the changes in this post can be found here.

Using NSwag to Generate Angular Client for an ASP.NET Core 3 API Read More »

Use HTTP Client Factory with NSwag Generated Classes in ASP.NET Core 3

In last week’s post, Using NSwag to Generate C# Client Classes for ASP.NET Core 3, we left off with a usable client, but we were missing out on using some of the features provided by ASP.NET Core such as the HTTP Client Factory and utilizing dependency injection.

Changes to NSwag Client Generation

This post is only going to point out the difference needed to help enable utilization of the ASP.NET Core features mentioned above and won’t be a full walkthrough of using NSwag. If you need a reference for what this post is covering make sure and read last week’s post.

The one change needed from last week’s post is to check Generate interfaces for Client classes.

With the above checked the client class can be regenerated and the files in the consuming application updated.

Using HTTP Client Factory and Dependency Injection

In the consuming application, we need to add the following to line in the ConfigureServices function of the Startup class to add an HTTP Client specifically for our Contacts API and make it available via the dependency injection system.

services.AddHttpClient<IContactsClient, ContactsClient>(client => 
           client.BaseAddress = new Uri("https://localhost:5001"));

For a production application, I would recommend using the configuration system to store the URL for the API instead of hardcoded like it is above.

For example usage, I’m using the IndexModel. First,  add a class-level field to hold our API client and inject the client via the constructor.

private readonly IContactsClient _contactsClient;

public IndexModel(ILogger<IndexModel> logger, IContactsClient contactsClient)
{
    _logger = logger;
    _contactsClient = contactsClient;
}

Now that we have a contacts client at the class-level we can use it get data from our API. The following example uses the client to get all the contacts from the API and stores them in a variable.

public async Task OnGet()
{
    var contacts = await _contactsClient.GetContactsAsync();
}

Wrapping Up

I highly recommend using this style of client vs. using HTTP client directly. If you do some searching you will find that managing the lifetime of HTTP client in .NET before the HTTP client factory was something that is easy to screw up.

The following posted were used as references:

Generating a Typed Client for use with HttpClientFactory using NSwag
How to add generated HttpClient to ASP.NET Core dependency injection

Use HTTP Client Factory with NSwag Generated Classes in ASP.NET Core 3 Read More »

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.

The following is the same style post for different frontends.

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

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.

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