Web API

ASP.NET Core Basics: React with an API

In the past, I have done some exploration on Aurelia and Angular via the ASP.NET Core Basics series. This post is going to take a similar approach as I start doing some exploration with React. The code for the project will be in the same repo as the previous basics examples and will be utilizing the same API to pull data. The code before adding the React project can be found here.

This post is going to cover adding a React project to the existing using the React template that is now built into Visual Studio. The same thing can be accomplished using the .NET CLI so don’t feel like Visual Studio is required. The goal for the React project in this initial post will be to connect to the contacts API and download a list of contacts and render that to the screen. In future posts, I hope to expand this functionality to match that of the Aurelia and Angular projects.

Project Creation

Right-click and select Add > New Project.

In the Add New Project dialog select the ASP.NET Core Web Application. In the case of the sample, the project will be named React. Click OK to continue.

On the next screen make sure and select ASP.NET Core 2.0 and the React.js template. Then click OK.

The following is the resulting React project in the context of the full solution.

Next, make sure and run npm install from a command prompt in the React project’s directory to ensure all the npm packages get restored.

Adding the Contact List

Inside the ClientApp/components/ directory add a file name ContactList.tsx. TSX is the TypeScript version of the React JSX file type. The official docs on JSX can be found here. Since this is my first time working with React I took the FetchData.tsx file and copied the contents and used that as the starting point for my contact list. To lead with there is an interface for what should define a contact.

interface Contact {
    id: number;
    name: string;
    address: string;
    city: string;
    state: string;
    postalCode: string;
    phone: string;
    email: string;
}

Next, we have an interface for the state of this component with contains a loading flag and an array of contacts.

interface ContactListState {
    contacts: Contact[];
    loading: boolean;
}

In the constructor for the component is where the data is pulled from the API using fetch. The data from the API is then saved to the state of the component using the setState function.

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

    fetch('http://localhost:13322/api/contactsApi/')
        .then(response => response.json() as Promise<Contact[]>)
        .then(data => {
            this.setState({ contacts: data, loading: false });
        });
}

Next, the component has a function named renderContactsTable which takes an array of contacts and returns how they should be rendered. In this case, the contacts are rendered to a table that displays the contact ID and Name.

private static renderContactsTable(contacts: Contact[]) {
    return <table className='table'>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            {contacts.map(contact =>
                <tr key={contact.id}>
                    <td>{contact.id}</td>
                    <td>{contact.name}</td>
                </tr>
            )}
        </tbody>
    </table>;
}

Finally, there is the render function. As you can guess this is what gets called to render the component. In this case, either “Loading” or the contact list gets displayed depending on if the contact list data has been loaded or not.

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

    return <div>
        <h1>Contact List</h1>
        {contents}
    </div>;
}

The following is the full file for reference.

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import 'isomorphic-fetch';

interface ContactListState {
    contacts: Contact[];
    loading: boolean;
}

export class ContactList extends React.Component<RouteComponentProps<{}>, ContactListState> {
    constructor() {
        super();
        this.state = { contacts: [], loading: true };

        fetch('http://localhost:13322/api/contactsApi/')
            .then(response => response.json() as Promise<Contact[]>)
            .then(data => {
                this.setState({ contacts: data, loading: false });
            });
    }

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

        return <div>
            <h1>Contact List</h1>
            {contents}
        </div>;
    }

    private static renderContactsTable(contacts: Contact[]) {
        return <table className='table'>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                </tr>
            </thead>
            <tbody>
                {contacts.map(contact =>
                    <tr key={contact.id}>
                        <td>{contact.id}</td>
                        <td>{contact.name}</td>
                    </tr>
                )}
            </tbody>
        </table>;
    }
}

interface Contact {
    id: number;
    name: string;
    address: string;
    city: string;
    state: string;
    postalCode: string;
    phone: string;
    email: string;
}

Add Contact List to Navigation

Now that we have the contact list component it needs to be added to the navigation menu. The first step is to add it to the application’s router. This can be found in the routes.tsx file. The file is short so I am going to include the full content. Lines 7 and 13 are the ones added to handle our contact list.

import * as React from 'react';
import { Route } from 'react-router-dom';
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';

export const routes = <Layout>
    <Route exact path='/' component={Home} />
    <Route path='/counter' component={Counter} />
    <Route path='/fetchdata' component={FetchData} />
    <Route path='/contactlist' component={ContactList} />
</Layout>;

The last change is to add a navigation link to the NavMenu found in the NavMenu.tsx file. As I am sure most of us are used to adding an item to the nav menu is just adding a new li, but with the React specific NavLink bit.

<li>
  <NavLink to={'/contactlist'} activeClassName='active'>
      <span className='glyphicon glyphicon-th-list-alt'></span> Contact List
  </NavLink>
</li>

Wrapping Up

React is different than both Aurelia and Angular. Don’t take that as a good or bad thing. I don’t plan to pick on a side on the Angular vs React debate I just want to get a good feel for the different frameworks. So far the React experience has been pretty nice and I look forward to doing more exploration.

You can find the finished code for this post here.

ASP.NET Core Basics: React with an API Read More »

Swagger and Swashbuckle: Disable Try It Out

In last week’s post, I walked through adding Swagger support to an ASP.NET Core 2 API using the Swashbuckle. One of the awesome things about Swashbuckle is it provides an integration with swagger-ui.

Try it out!

One of the features of the UI integration is the ability to invoke an end point using the “Try it out!” button. This feature is awesome during development but may not be something you want to allow, depending on the use case, for a production end point.

Disable Try it out!

I tried googling lots of different things to find the option to disable the “Try it out” button and had a really hard time finding an answer. It didn’t help that I want the button text to be “Try it now” for some reason. Thankfully it truly was a failure on my part and there is a provided way to disable “Try it out” and it is much more flex able than what I was initially looking for.

In the Configure function of the Startup class find the call to app.UseSwaggerUI. Adding c.SupportedSubmitMethods(new string[] {}); will completely disable “Try it out”. The following is the full call to app.UseSwaggerUI just to provide context.

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Contacts API V1");
    c.SupportedSubmitMethods(new string[] {});
});

The great thing about the way this is set up if you can allow some actions and not others. For example, say you wanted to allow get actions but disable the rest. The following would allow for that.

c.SupportedSubmitMethods(new [] {"get"});

One word of caution the above is case sensitive and if you use Get instead of get “Try it out” will remain disabled.

Swagger and Swashbuckle: Disable Try It Out Read More »

Swagger and Swashbuckle with ASP.NET Core 2

This post is going to be very similar to a post from last December which can be found here. A lot has changed since then and this post is going to add Swagger to an existing ASP.NET Core application using Swashbuckle much like the one from last year. The starting point of the code can be found here.

What is Swagger?

Swagger is a specification used to document an API. As I am sure we all know API documentation tends to get out of date fast and a lot of times is a low priority.  Swagger aims to help solve that problem using a format that is both human and machine readable which can be maintained in either JSON or YAML. The documentation can be auto generated using a tool like Swashbuckle which provides away to keep your consumers up to date. Check out this post by the Swagger team for the full introduction.

What is Swashbuckle?

Swashbuckle provides auto generation of Swagger 2.0, a UI, etc. The project takes all the pain out of getting going with Swagger as well as providing tools and hooks for using and customizing Swagger related items. The full description can be found here.

Adding Swashbuckle

Using your favorite method of NuGet interaction, add the Swashbuckle.AspNetCore NuGet package to your project. Personally, I have gotten where I edit the csproj file to add new packages. If that is your style you would need to add the following package reference.

<PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" />

This one package provides all the functionality we will need.

Wiring up Swashbuckle

Now that the Swashbuckle package is installed, there are a few changes that are needed in the Startup class to get everything wired up. First, in the ConfigureServices function, the Swagger generator needs to be added to DI.

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Info { Title = "Contacts API", Version = "v1"});
});

AddSwaggerGen allows for configuration of options, but here we are just setting a name and a minimal amount of information.

In the Configure function Swagger needs to be added to the request pipeline in order to expose the Swagger generated data. I placed this after UseMvc.

app.UseSwagger();

At this point, the Swagger generated JSON would be available at {yourBaseUrl}/swagger/v1/swagger.json. To take a step further let’s expose the UI that comes with Swashbuckle. Add the following just below app.UseSwagger().

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Contacts API V1");
});

Now a UI based on your API is available at {yourBaseUrl}/swagger with zero extra work on your part. The following is the UI for the post contact route in the example project.

As you can see the UI provides a great view of your API as well as ways to try it out and the potential responses that should be expected from a call.

Controller Considerations

All of this wonderful functionality doesn’t come for free of course. In order for Swashbuckle to pick up your routes, your controller will need to use attribute based routing instead of depending on convention based routing.

In order for Swashbuckle to know the return types and of your controller actions may need to have some attributes added. This won’t be required if your action return a specific type, but if you are returning an IActionResult you should attribute your action with all the ProducesResponseType you need to cover the results of your action. For example, the following is the action definition for the Post in the screen shot above.

[HttpPost]
[ProducesResponseType(typeof(Contact), 200)]
[ProducesResponseType(typeof(IDictionary<string, string>), 400)]
[ProducesResponseType(typeof(void), 400)]
[ProducesResponseType(typeof(void), 404)]
[ProducesResponseType(typeof(void), 409)]
public async Task<IActionResult> PostContact([FromBody] Contact contact)

Wrapping up

Swashbuckle makes it easy to add Swagger to a project. I feel that it also provides a huge value for anyone trying to consume an API. It is of course not a magic bullet and communication with your API consumers about API changes will still be critical.

Microsoft’s docs have a great walk through which can be found here. It does more in-depth on customizing your setup and as far as modifying the look of the UI. I also recommend checking out the GitHub page for the project which can be found here.

The finished code can be found here.

Swagger and Swashbuckle with ASP.NET Core 2 Read More »

Identity Server: Introduction

In the SPA based sample applications, this blog has used so far user authentication has either been completely ignored in order to keep the examples simpler or the sites have used ASP.NET Core’s built in identity to encapsulate the whole SPA. In this post (or series of posts) I am going to share what I learn along the way of creating an Angular (2+) application that utilizes ASP.NET Core as its host/API/backend.

This post isn’t going to cover any code it is just going to be a lot of the information I gathered in the process of learning more about Identity Server.

Following are all the post in this series.

Identity Server: Introduction (this post)
Identity Server: Sample Exploration and Initial Project Setup
Identity Server: Interactive Login using MVC
Identity Server: From Implicit to Hybrid Flow
Identity Server: Using ASP.NET Core Identity
Identity Server: Using Entity Framework Core for Configuration Data
Identity Server: Usage from Angular

Identity Server

According to their docs IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core which enables Authentication as a Service, Single Sign-on, API Access Control and a Federation Gateway.

Obviously, that covers a lot of scenarios. The two that I am interested in are Authentication as a Service and the API Access Control which has driven my research which means that the other aspects of IdentityServer4 will not be included.

Official Samples

The IdentityServer GitHub account has a samples repo that contains a ton of examples. I have found the quickstart area of the repo to be the most helpful when starting out.

Based on all the quickstarts samples it looks like a typical setup involves a minimum of three projects. One for the API, one for the client and one for Identity Server. As you go through the samples the number of projects increase, but that is because of a wider range of scenarios that the sample is trying to cover.

References for learning

Damienbod has a whole series of blog posts related to IdentityServer4 and code to go along with it which can be found here. As a side note if you are interested in ASP.NET Core and you aren’t following damienbo you should be he has a ton of great content.

Blog posts
Videos

Identity Server Alternatives

Identity Server isn’t the only way to go there is a number of Software as a Service options that cover a lot of same scenarios. The following are some examples.

Auth0 – Check out the .NET Core related blogs by Jerrie Pelser
Stormpath
Amazon Cognito

Wrapping up

Obviously, I didn’t get a lot covered on how to actually do something with IdentityServer, but I wanted to share my starting point. This is an area I am going to continue digging it to and sharing information about as I learn more.

If you have any resources in this area please leave a comment below.

Identity Server: Introduction Read More »

Angular 2 Contact Creation and Post to an API

Expanding on this post which created a placeholder for creating new contacts this post will create an actual UI and post the newly created contact to an ASP.NET Core API. The code before any changes can be pulled using this release tag. Keep in mind all changes in this post take place in the Angular project if you are using the associated sample.

Contact service changes to all post

The contract service found in the contact.service.ts file of the ClientApp/app/components/contacts/ directory is used to encapsulate interaction with the associated ASP.NET Core API and prevent access to Angular’s Http library from being spread across the application. The first change is to expand the existing import of Angular’s Http library to include Headers and RequestOptions.

import { Http, Headers, RequestOptions } from '@angular/http';

Next, a save is added that makes a post request to the ASP.NET Core API with the body set to a JSON version of the contact to be added.

save(contact: Contact): Promise<Contact> {
   let headers = new Headers({ 'Content-Type': 'application/json' });
   let options = new RequestOptions({ headers: headers });

   return this.http.post(this.baseUrl, JSON.stringify(contact), options)
        .toPromise()
        .then(response => response.json())
        .then(contact => new Contact(contact))
        .catch(error => console.log(error));
}

The API will return the created contact with the ID now filled in which will be returned to the caller. As I have said before catching the error and just writing it to the console isn’t the proper way to handle errors and this should be done in a different manner for a production application.

Contact detail view model

The view model that backs the contact detail view needed a function to allow saving of a contact. The following code uses the contact service to save a contact and then replace its local contact with the new one returned from the API. Finally, the class level variable indicating if the view model is in create or detail mode is set to true which triggers the UI to change out of create mode.

save() {
     this.contactService.save(this.contact)
         .then(contact => this.contact = contact)
         .then(() => this.hasContactId = true);
}

You will see in the sample code that a second function was added for reset which is a quick way to reset the create UI.

reset() {
    this.contact = new Contact();
}

Contact model

The constructor of the contact class changed to make the data parameter optional to allow for the creation of an empty contact.

constructor(data?) {
    if (data == null) return;
    Object.assign(this, data);
}

Include Angular Forms

For the two-way binding needed on the contact detail page Angular forms will be used. To include them in the project open the app.module.ts file in the ClientApp/app/ directory. Add the following import.

import { FormsModule } from '@angular/forms';

Then add FormsModule to the imports array.

imports: [
     UniversalModule,
     FormsModule,
     RouterModule.forRoot([

Contact detail view

The following is the full contact view as it stands with all of the needed changes made. This will be followed by call outs of some of the important items.

 <h1>Contact Details</h1>
  <hr />
  <div *ngIf="hasContactId">
      <dl class="dl-horizontal">
          <dt>ID</dt>
          <dd>{{contact.id}}</dd>
         <dt>Name</dt>
         <dd>{{contact.name}}</dd>
         <dt>Address</dt>
         <dd>{{contact.getAddress()}}</dd>
         <dt>Phone</dt>
         <dd>{{contact.phone}}</dd>
         <dt>Email</dt>
          <dd>{{contact.email}}</dd>
      </dl>
  </div>
 <div *ngIf="!hasContactId">
     <div>
         <form role="form" class="form-horizontal">
             <div class="form-group">
                 <label class="col-sm-2 control-label">Name</label>
                 <div class="col-sm-10">
                     <input type="text" 
			    placeholder="name" 
			    class="form-control" 
                            [(ngModel)]="contact.name" 
			    name="name" />
                 </div>
             </div>
             <div class="form-group">
                 <label class="col-sm-2 control-label">Address</label>
                 <div class="col-sm-10">
                     <input type="text" 
			    placeholder="address" 
			    class="form-control" 
			    [(ngModel)]="contact.address" 
			    name="address" />
                 </div>
             </div>
             <div class="form-group">
                 <label class="col-sm-2 control-label">City</label>
                 <div class="col-sm-10">
                     <input type="text" 
			    placeholder="city" 
			    class="form-control" 
			    [(ngModel)]="contact.city" 
			    name="city" />
                 </div>
             </div>
             <div class="form-group">
                 <label class="col-sm-2 control-label">State</label>
                 <div class="col-sm-10">
                     <input type="text" 
			    placeholder="state" 
			    class="form-control" 
			    [(ngModel)]="contact.state" 
			    name="state" />
                 </div>
             </div>
             <div class="form-group">
                 <label class="col-sm-2 control-label">Zip</label>
                 <div class="col-sm-10">
                     <input type="text" 
			    placeholder="zip" 
			    class="form-control" 
			    [(ngModel)]="contact.postalCode" 
			    name="postalCode" />
                 </div>
             </div>
             <div class="form-group">
                 <label class="col-sm-2 control-label">Phone</label>
                 <div class="col-sm-10">
                     <input type="text" 
			    placeholder="phone" 
			    class="form-control" 
			    [(ngModel)]="contact.phone" 
			    name="phone" />
                 </div>
             </div>
             <div class="form-group">
                 <label class="col-sm-2 control-label">Email</label>
                 <div class="col-sm-10">
                     <input type="email" 
			    placeholder="email" 
			    class="form-control" 
			    [(ngModel)]="contact.email" 
			    name="email" />
                 </div>
             </div>
         </form>
     </div>
     <div class="text-center">
         <button class="btn btn-success btn-lg" 
		 (click)="save()">Save</button>
         <button class="btn btn-danger btn-lg" 
		 (click)="reset()">Reset</button>
     </div>
 </div>
  <a routerLink="/contact-list">Back to List</a>
  <hr />

All control of content rendering has been changed to use hasContactId.

Default view:
<div *ngIf="hasContactId">

Create view:
<div *ngIf="!hasContactId">

For the creation UI, the data is bound using Angular’s ngModel binding.

<input type="text" 
       placeholder="address" 
       class="form-control" 
       [(ngModel)]="contact.address" 
       name="address" />

If you have any issues make sure and check that you have the name attribute set to the property you are wanting to bind to.

The last thing to point out is the click handlers that are used to call the associate save and rest functions with the Save and Reset buttons are clicked.

<button class="btn btn-success btn-lg" 
        (click)="save()">Save</button>
<button class="btn btn-danger btn-lg" 
        (click)="reset()">Reset</button>

Wrapping up

Now the application has the ability to add contact not just view them which is one step closer to what would be needed for a real application. The finished code can be found here.

Angular 2 Contact Creation and Post to an API Read More »

Aurelia Contact Creation and Post to an API

Expanding on this post where a placeholder was added for contact creation the placeholder will be replaced with an actual UI. As part of the contact creation process, Aurelia’s fetch client will be used to make a post request to the ASP.NET API. The code at the starting point can be found here. If using the sample code keep in mind all the changes in this post takes place in the Aurelia project.

Contact service changes to allow post

In this project a service is used to keep all the Http bits isolated from the rest of the application. In the contactService.ts file found in the ClientApp/app/components/contacts/ directory a couple of changes need to be made. First the fetch import needs to expose json in addition to HttpClient.

import { HttpClient, json } from 'aurelia-fetch-client';

Then a save function is added that makes a post request to the ASP.NET API and return a new contact based on the response from the post request. The contact in the post response will contain the ID assigned by the API.

save(contact: Contact): Promise<Contact> {
    return this.http.fetch('',
        {
            method: 'post',
            body: json(contact)
        })
        .then(response => response.json())
        .then(contact => new Contact(contact))
        .catch(error => console.log(error));
}

Notice the usage of json to serialize the contact being create to JSON before sending to the server. Also, note that just logging an error to the console isn’t a best practice and should be handling in a different way in a production application.

Contact detail view model

The view model that backs the contact detail view needed a function to allow saving of a contact. The following code uses the contact service to save a contact and then replace its local contact with the new one returned from the API. Finally, the class level variable indicating if the view model is in create or detail mode is set to true which triggers the UI to change out of create mode.

save() {
     this.contactService.save(this.contact)
         .then(contact => this.contact = contact)
         .then(() => this.hasContactId = true);
}

You will see in the sample code that a second function was added for reset which is a quick way to reset the create UI.

reset() {
    this.contact = new Contact();
}

Contact model

The constructor of the contact class changed to make the data parameter optional to allow for the creation of an empty contact.

constructor(data?) {
    if (data == null) return;
    Object.assign(this, data);
}

Contact detail view

The view under when the most changes and the following is the entirety of the UI file which can be found in the contactDetail.html file. The code will be followed up with call outs for the important bits.

 <template>
      <h1>Contact Details</h1>
      <hr />
      <div if.bind="hasContactId">
          <dl class="dl-horizontal">
              <dt>ID</dt>
              <dd>${contact.id}</dd>
             <dt>Name</dt>
             <dd>${contact.name}</dd>
             <dt>Address</dt>
             <dd>${contact.getAddress()}</dd>
             <dt>Phone</dt>
             <dd>${contact.phone}</dd>
             <dt>Email</dt>
              <dd>${contact.email}</dd>
          </dl>
      </div>
     <div if.bind="!hasContactId">
         <div>
             <form role="form" class="form-horizontal">
                 <div class="form-group">
                     <label class="col-sm-2 control-label">Name</label>
                     <div class="col-sm-10">
                         <input type="text" 
                                placeholder="name" 
                                class="form-control" 
                                value.bind="contact.name" />
                     </div>
                 </div>
                 <div class="form-group">
                     <label class="col-sm-2 control-label">Address</label>
                     <div class="col-sm-10">
                         <input type="text" 
                                placeholder="address" 
                                class="form-control" 
                                value.bind="contact.address" />
                     </div>
                 </div>
                 <div class="form-group">
                     <label class="col-sm-2 control-label">City</label>
                     <div class="col-sm-10">
                         <input type="text" 
                                placeholder="city" 
                                class="form-control" 
                                value.bind="contact.city" />
                     </div>
                 </div>
                 <div class="form-group">
                     <label class="col-sm-2 control-label">State</label>
                     <div class="col-sm-10">
                         <input type="text" 
                                placeholder="state" 
                                class="form-control" 
                                value.bind="contact.state" />
                     </div>
                 </div>
                 <div class="form-group">
                     <label class="col-sm-2 control-label">Zip</label>
                     <div class="col-sm-10">
                         <input type="text" 
                                placeholder="zip" 
                                class="form-control" 
                                value.bind="contact.postalCode" />
                     </div>
                 </div>
                 <div class="form-group">
                     <label class="col-sm-2 control-label">Phone</label>
                     <div class="col-sm-10">
                         <input type="text" 
                                placeholder="phone" 
                                class="form-control" 
                                value.bind="contact.phone" />
                     </div>
                 </div>
                 <div class="form-group">
                     <label class="col-sm-2 control-label">Email</label>
                     <div class="col-sm-10">
                         <input type="email" 
                                placeholder="email" 
                                class="form-control" 
                                value.bind="contact.email" />
                     </div>
                 </div>
             </form>
         </div>
         <div class="text-center">
             <button class="btn btn-success btn-lg" 
                     click.delegate="save()">Save</button>
             <button class="btn btn-danger btn-lg" 
                     click.delegate="reset()">Reset</button>
         </div>
     </div>
     <div>
         <a route-href="route: contactlist">Back to List</a>
     </div>
      <hr />
  </template>

All control of content rendering has been changed to use hasContactId.

Default view:
<div if.bind="hasContactId">

Create view:
<div if.bind="!hasContactId">

For the creation UI, the data is bound using Aurelia’s value converters for more detail see the docs. The value converter is the value.bind bit.

<input type="text" 
       placeholder="name" 
       class="form-control" 
       value.bind="contact.name" />

The last thing to point out is the click delegates that are used to call the associate save and rest functions with the Save and Reset buttons are clicked.

<button class="btn btn-success btn-lg" 
        click.delegate="save()">Save</button>
<button class="btn btn-danger btn-lg" 
        click.delegate="reset()">Reset</button>

Wrapping up

The application now has the ability to add contact instead of only viewing existing contact which brings it close to a more realistic application. The code in its finished state can be found here.

The plan is to continue iterating on this application and moving the Aurelia and Angular 2 projects in parallel. I hope this is useful and if you have any specific features you would like to see implemented leave a comment.

Aurelia Contact Creation and Post to an API Read More »

Swagger and Swashbuckle with ASP.NET Core API

This post is going to walk through adding Swagger to an existing ASP.NET Core API application using Swashbuckle. The starting point for the code can be found here.

What is Swagger?

Swagger is a specification on documentation an API. As I am sure we all know API documentation tends to get out of date fast and a lot of times is a low priority.  Swagger aims to help solve that problem using a format that is both human and machine readable which can be maintained in either JSON or YAML and can be auto generated using a tool like Swashbuckle. Check out this post by the Swagger team for the full introduction.

What is Swashbuckle?

Swashbuckle provides auto generation of Swagger 2.0, swagger-ui integration, etc. The project takes all the pain out of getting going with Swagger as well as providing tools and hooks for using and customizing Swagger related items. The full description can be found here.

Adding Swashbuckle to the project

There are lots of ways to get a new package into an ASP.NET Core application and the following covers the NuGet UI, Package Manager Console and Project.json. Pick one of them to use.

NuGet UI

Right click on the project Swashbuckle is going to be added to, Contacts in the case of the sample code, and select Manage NuGet Packages.

swashbuckleprojectmenu

Select the Browse tab, check the Include prerelease checkbox and search for Swashbuckle. Prerelease is need to get the version that works with ASP.NET Core.

swashbucklenuget

Finally click the Install button and work though any confirmation dialog screens that might show.

Package manager console

From the package manager console run Install-Package Swashbuckle -Pre.

Project.json

Open porject.json and in the dependencies section add “Swashbuckle”: “6.0.0-beta902”.

Add and configure Swashbuckle

In the ConfigureServices function of the Startup class add the following. I added it as the end, but placement shouldn’t matter.

services.AddSwaggerGen();

Next in the Configure function after app.UseMvc add the following.

app.UseSwagger();
app.UseSwaggerUi();

The first line enable serving of the Swagger JSON endpoint and the second enables the swagger-ui.

Test it out

Running the application will now provide two new routes one or each of the items added to the Configure function above.

The first is http://localhost:13322/swagger/v1/swagger.json (your base URL may differ if not using the sample procject) and it exposes the Swagger compliant JSON.

The second URL is http://localhost:13322/swagger/ui and it provides a very readable view of the documented API along with examples and options to try the API out. The following as an example of what the current version outputs.

swaggeruiexample

Wrapping up

Swashbuckle make it easy to add Swagger to a project. I feel that it also provides a huge value for anyone trying to consume an API. It is of course not a magic bullet and communication with your API consumers about API changes will still be critical.

Microsoft’s docs has a great walk through which can be found here. It does more in-depth on customizing your setup and as far as modifying the look of the UI.

The code for this post in it’s finished state can be found here.

Swagger and Swashbuckle with ASP.NET Core API Read More »

Angular 2 with an ASP.NET Core API

This week’s post is going to take the Angular 2 application from a couple of weeks ago and add the same functionality currently present in the Aurelia application found the ASP.NET Core Basic repo. This release is the starting point for the solution used in this post.

Starting point overview

When you download a copy of the repo you will find an ASP.NET Core solution that contains three projects. The Angular project is where this post will be focused.

The Contacts project has a set of razor views and a controller to go with them that support standard CRUD operations, which at the moment is the best way to get contact information in the database. It also contains the ContactsApiController which will be the controller used to feed contacts to the Angular 2 and Aurelia applications.

Multiple startup projects in Visual Studio

In order to properly test the functionality that will be covered here both the Contacts project and the Angular project will need to be running at the same time. Visual Studio provides a way to handle this. The Multiple startup projects in Visual Studio section of this post walks through the steps of setting up multiple startup project. The walk through is for the Aurelia project, but the same steps can be applied to the Angular project.

Model

Create a contacts directory inside of ClientApp/app/components/ of the Angular project. Next create a contact.ts file to the contacts directory. This file will be the model of a contact in the system. If you read the Aurelia version of this post you will noticed that this model is more fully defined since this project is using TypeScript the more fully defiled model provides more type safety. The following is the contests file.

export class Contact {
    id: number;
    name: string;
    address: string;
    city: string;
    state: string;
    postalCode: string;
    phone: string;
    email: string;

    constructor(data) {
        Object.assign(this, data);
    }

    getAddress() {
        return `${this.address} ${this.city}, ${this.state} ${this.postalCode}`;
    }

}

Service

To isolate HTTP access the application will use a service to encapsulate access to the ASP.NET Core API. For the service create a contact.service.ts file in the contacts directory of the Angular project. The following is the code for the service.

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Contact } from './contact';

@Injectable()
export class ContactService {

    constructor(private http: Http) {
    } 

    getAll(): Promise<Contact[]> {
        return this.http.get('http://localhost:13322/api/contactsApi/')
            .toPromise()
            .then(response => response.json())
            .then(contacts => Array.from(contacts, c => new Contact(c)))
            .catch(error => console.log(error));
    }
}

This class uses Angular’s HTTP client to access the API and download a list of contacts. Angular’s HTTP client uses reactive extensions and returns an observable. In this case we don’t need an observable so for this service the observable is being converted to a promise. Then from there the response from the API is being converted an array of type contact.

Also make note of the Injectable decorator which tells Angular 2 the class should be available for dependency injection.

View Model

The next step is to create a view model to support the view that will be used to display the contacts download from the API. Add a file named contactlist.component.ts to the contacts directory of the Angular project. The following is the full contents of the view model file. This will be followed by a breakdown of the file in order to highlight some parts of the file.

import { Component, OnInit } from '@angular/core';
import { Contact } from './contact';
import { ContactService } from './contact.service';

@Component({
    selector: 'contactlist',
    template: require('./contactlist.component.html'),
    providers: [ContactService]
})
export class ContactListComponent implements OnInit {
    contacts: Contact[];

    constructor(private contactService: ContactService) { }

    ngOnInit(): void {
        this.contactService.getAll()
            .then(contacts => this.contacts = contacts);
    }
}

The import statements are pulling in a couple parts of the Angular 2 framework in addition to the contact model and contact service created above.

Next is a component decorator which marks the class as an Angular component and provides a method to set metadata about the class.

@Component({
    selector: 'contactlist',
    template: require('./contactlist.component.html'),
    providers: [ContactService]
})

The selector property sets the identifier for the class to be used in templates. The template property sets the view that should be used with the view model. In this case it is requiring in another file, but it could also contain the actual template that should be used to render the component. An alternate is to use templateUrl to point to an external file containing a template. The final property used in this example is the providers  property which is a list of providers that the framework needs to be made available to the component, in this case the ContractService. For more information on the component decorator check out the Angular docs.

The next thing of note on this class is that it implements OnInit.

export class ContactListComponent implements OnInit

OnInit is one of Angular’s lifecycle hooks, see the docs for the rest of the available hooks. OnInit is called once after component creation and runs the ngOnInit function which in the case of this class is being used to get a list of contacts from the ContactService.

View

For the view create a contactlist.component.html in the contacts directory of the Angular project. This is the file that the veiw model created above is bound with to display the contact data retrieved from the API. The following is the complete contents of the view file.

<ul>
    <li *ngFor="let contact of contacts">
        <h4>{{contact.name}}</h4>
        <p>{{contact.getAddress()}}</p>
    </li>
</ul>

The second line repeats the li tag for each contact in the contacts array of the view model class. {{expression}} is Angular’s syntax for one way data binding. {{contact.name}} does a one way binding to the name property of the current contact in the *ngFor loop. For more details on the different options available for data binding see the docs.

Add menu

The final piece is to add an item to the menu from with the contact list can be accessed. Open app.module.ts in the ClientApp/app/components/ directory. Add an imports for the ContactListComponent.

import { ContactListComponent } from './components/contacts/contactlist.component';

Next add a new path to the RouterModule. The third from the bottom is the line that was added for the contact list.

RouterModule.forRoot([
    { path: '', redirectTo: 'home', pathMatch: 'full' },
    { path: 'home', component: HomeComponent },
    { path: 'counter', component: CounterComponent },
    { path: 'fetch-data', component: FetchDataComponent },
    { path: 'contact-list', component: ContactListComponent },
    { path: '**', redirectTo: 'home' }
])

Finally open the navmenu.component.html file in the ClientApp/app/components/navmenu/  directory. Add a new li for the contact list matching the following.

<li [routerLinkActive]="['link-active']">
    <a [routerLink]="['/contact-list']">
        <span class='glyphicon glyphicon-list-alt'></span> Contact List
    </a>
</li>

Wrapping up

That is all it takes to consume some data from an ASP.NET Core API and use it in an Angular 2 application. I can’t stress enough how easy working with in the structure provided by JavaScriptServices helped in getting this project up and going quickly.

The completed code that goes along with this post can be found here. Also note that the Aurelia project has be redone as well also based on JavaScriptServices and TypeScript so that the applications will be easier to compare.

Angular 2 with an ASP.NET Core API Read More »

Aurelia with an ASP.NET Core API

In last week’s post I covered creating a new ASP.NET Core project and then adding in Aurelia. The Aurelia application did nothing except output hello world. This week I am going to take an existing contacts API and the Aurelia project from last week use them together to make the Aurelia application display the name of the contacts from the API.

Part 1 – Add Aurelia to an ASP.NET Core Project
Part 2 – Aurelia with an ASP.NET Core API (This Post)
Part 3 – Aurelia with an ASP.NET Core API: Modeling and Displaying Data in Aurelia
Part 4 – Aurelia with ASP.NET Core: Host Aurelia from a Controller
Github repo with the code for all of the parts with a release to go with each post

Starting point overview

When you download a copy of the repo you will find an ASP.NET Core solution that contains two projects. The Aurelia project, obviously, contains the Aurelia application.

The Contacts project has a bit more going on. It has a set of razor views and a controllers to go with them that support standard CRUD operations, which at the moment is the best way to get contact information in the database. It also contains the ContactsApiController which will be the controller used to feed contacts to the Aurelia application.

Multiple startup projects in Visual Studio

In order to test this application both the Contacts and Aurelia projects to startup when the solution is run. Visual Studio provides an easy way to accomplish this. In the Solution Explorer window right click on the Solution and click Set StartUp Projects.

sestartup

This will launch the Solution Property Pages dialog. Looks for the Startup Project page under Common Properties.

multiplestartupprojects

Match the screenshot above by selecting the radio button for Multiple startup projects. Then using the arrows on the right to make sure that Contacts project will start first. Also set the Action on Contacts to be start without debugging since that project will just be feeding data and won’t need to be debugged at the moment.

Then on the Aurelia project set the Action to Start. Click OK and now both projects will start up when solution is run from Visual Studio.

Accessing Data from the API

In order to get data from the API we will need away to talk HTTP from Aurelia. Aurelia provides two libraries that provide this functionality which you can read about here. For this post I will be using Aurelia’s fetch client which based on the experimental Fetch API. The Fetch API isn’t supported by all browsers at point so if you need it there a polyfill can be found here.

Installing the Aurelia Fetch Client

If you started with the project from GitHub repo linked about then the fetch client will already be included in the projects dependencies, but if not I wanted to cover getting it installed. Using a command prompt run the following npm command in the project’s directory.

npm install aurelia-fetch-client -save

Alternately add the following line to the dependencies section of the project’s package.json file and when the file is saved Visual Studio will automatically restore the new package.

"aurelia-fetch-client": "^1.0.0"

The last step to making sure the fetch client available in the client application is to make sure it is included in the vendor-bundle.js that is created by the Aurelia CLI’s build process. To do this open the aurelia.json file found in the aurelia_project folder. In the bundles section look for the bundle named vendor-bundle.js and in its dependencies section add “aurelia-fetch-client”. The following an abbreviated example from my file to to make it clear where the new line should go.

"name": "vendor-bundle.js",
"prepend": [
  "node_modules/bluebird/js/browser/bluebird.core.js",
  "wwwroot\\scripts/require.js"
],
"dependencies": [
  "aurelia-binding",
  "aurelia-bootstrapper",
  "aurelia-dependency-injection",
  "aurelia-event-aggregator",
  "aurelia-fetch-client",

Create a client side service

It is important to not spread HTTP across the whole application and in order to achieve this goal it is a good idea to create a service that encapsulates the HTTP actions. For this example a contact service will be created that will handle all interactions with the ASP.NET Core API and the rest of the Aurelia application will just interact with the contact service.

To start create a services folder inside the src folder which contains the Aurelia client side application and added a new file to contain the new service called contactService.js.

nfcontactservice

The contact service will use the Aurelia fetch client to get all the contacts from the ASP.NET Core API. To do so it needs a constructor to allow injection and configuration of a HTTP client as well as a single function to get all the contacts. The following is the complete service.

import { HttpClient } from 'aurelia-fetch-client';

export class ContactService {
    static inject() { return [HttpClient] };

    constructor(http) {
        this.http = http;

        this.http.configure(config => {
            config
                .useStandardConfiguration()
                .withBaseUrl('https://localhost:13322/api/contactsApi/');
        });
    }

    GetAll() {
       return this.http.fetch('')
            .then(response => response.json())
            .catch(error => console.log(error));
    }
}

A future post will come back to this code and make it more robust, but this post is just about getting data for the Aurelia application so the service is being kept as simple as possible.

Using the Contact Service

Again to keep the code as simple as possible the contact servers will be utilized directly in existing the existing app.js file. The following is the class before any changes.

export class App {
  constructor() {
    this.message = 'Hello World!';
  }
}

The following is the class after the changes to import and inject the contact service via the constructor as well as using the contact service to download and show the name of each contact.

import { ContactService } from './services/contactService';

export class App {
    static inject() { return [ContactService] };

    constructor(contactService) {
        this.message = 'Hello World!';
        contactService.GetAll()
            .then(result => {
                this.message = `Contact Results: 
                                ${result.map((contact) => contact.name)}`;
            });
    }
}

Does it work?

At this point I used Visual Studio to launch both projects. In the Aurelia MVC application I navigated to http://localhost:37472/index.html which is the page that contains the Aurelia client application. Instead of being greeted by a list of contact names the application output “Hello World!”. That means that the Aurelia client application was running, but the contact service had failed for some reason. The console in the Chrome developer tools show the following error.

Fetch API cannot load http://localhost:13322/api/contactsApi/. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:37472’ is therefore not allowed access. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

The work around

Turns out that having two projects caused an issue I hadn’t considered. I now have to worry about cross-origin resource sharing. Not a topic that will be covered in this post. In order to work around this issues the Contacts project can be changed to added the following to the Configure function of the Startup class.

app.UseCors(builder =>
    {
        builder.AllowAnyHeader();
        builder.AllowAnyMethod();
        builder.AllowAnyOrigin();
    }
);

I am in no way saying that the above is the proper way to fix this issue. CORS is a subject I haven’t dug in to yet. The above is only meant to get this sample working. Please make sure to locate other resources on CORS for anything that is more than a demo.

Final thoughts

Running at this point will return the names of contacts as expected. Future posts will expand this application more. I want to get Angular 2 up as a new project in this same solution. When this solution has projects that contains the basics for MVC/razor, Aurelia and Angular 2 it will be in a good replacement the ASP.NET SPAs comparison reference application. Having each type of front end in a different project should make it easier to follow how each is set up. The code for today’s post can be found here.

Aurelia with an ASP.NET Core API Read More »

ASP.NET Core Basics: API Controller

This week’s post is going to cover the creation of an API controller. The starting point for this post is based on this post from last week and the starting state of the code can be found here.

Scaffolding

Using the same Contact model class from last week’s post Entity Framework Core’s scaffolding can be used to generate an API controller for us with all the read and write actions already written. To begin in the Solution Explorer window right click on the Controllers folder and select Add > New Scaffolded Item.

AddNewScaffoldedItemMenu

On the Add Scaffold dialog select API Controller with actions, using Entity Framework. This option will create an API controller with read and write actions based on a model.

AddScaffoldApi

On the Add Controller dialog for the model class select the Contact class, for the data context class select the existing ContactsContext. Finally enter the controller name you would like to use. I am using ContactsApiController since the MVC controller from last week’s post is already named ContactsController.

AddApiControllerDialog

Click add and the scaffolding process will create a ContactsApiController in the Controllers folder. With that the project now contains a fully functional contacts API that will handle gets, puts, posts and deletes with zero code changes.

Test with Postman

Postman is a great tool that I always use when developing an API that allows me to exercise all the functions of the API before any clients have been built. I know you can do some of the same things using a browser, but Postman was built for this type of usage and it shows. Postman is free and you can grab it from here as a Chrome app or they have app versions available here.

After installing the application and running it you will see something like the following.

PostmanBlank

It is best to have some data available for testing so in the case of this application I recommend using the UI added in last weeks post to add a couple of contacts.

Now that some data is available it is time to test the GetContact function on the ContactsApiController. If you run the application it should open in a browser from which you can copy the URL, or right click on the project select properties then on the Debug tab copy the URL from the App URL field.

ProjectProperties

Paste the base URL in the URL box in Postman and then add on the route for the endpoint you are wanting to test. In this case I want to test the the GetContact function on the ContactsApiController so I will be using the a URL of http://localhost:13322/api/contactsapi. Next make sure contact application is running and then click the send button in Postman. The application should respond and the results of the API call will be displayed on the body tab of Postman.

PostmanGetContacts

Postman can be used to try out pretty much all aspects of the API that an application has. For example if you wanted to test out the PostContact then in Postman click the down arrow next to Get and select Post. Next select the upper body tab (in the request area) and the click the raw radio button. Then to the right of the radio buttons hit the down arrow and select JSON (application/json) and then it the large text box you can enter the JSON that will be sent to the server when you click the send button. The following is an example of a post request.

PostmanPostContact

Wrapping Up

This application now has a fully functional API and we have covered how test it using Postman.

The next step would be to create some sort of client to actually utilized the API such as an Aurelia or Angular 2 application.

The code for this post can be found here.

ASP.NET Core Basics: API Controller Read More »