ASP.NET Core

Aurelia – Router links, click delegate, routing parameters

This post is going to cover multiple of topics that I hit while creating a contact detail page to go along with the contact list that is part of my ASP.NET Basics repo. The code before any changes can be found here. If you are following along with the sample application keep in mind all the changes in this post take place in the Aurelia project.

Creating a detail view and view model

Create contactDetail.html file inside of ClientApp\app\components\contacts. This is the view that will be used to display all the details of a specific contact as well as a link back to the contact list. The following image shows the folder structure with the view and view model already added.

View

The following is the full contents of the view. This will be followed up few a calls out of Aurelia specific things going on.

<template>
    <h1>Contact Details</h1>
    <hr />
    <div if.bind="contact">
        <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>
    <a route-href="route: contactlist">Back to List</a>
    <hr />
</template>

if.bind will keep the contact details out of the DOM if the condition fails. In this case, if the contact is null.

${value} is one of Aurelia’s bind syntaxes. For more details check out their docs.

<a route-href=”route: contactlist”> is using Aurelia’s router to generate a link back to the contact list component.

View model

Next, create a contactDetail.ts file inside of ClientApp\app\components\contacts  which is the view model that goes with the view created above.

The view model gets an instance of the ContactService injected which is used to pull a contact’s detail information during the activate lifecycle hook. Notice the first parameter of the function (parms) which is where the route parameters are passed in.

import { inject } from 'aurelia-framework';
import { Contact } from './contact';
import { ContactService } from './contactService';

@inject(ContactService)
export class ContactDetail {
     contact: Contact;

    constructor(private contactService: ContactService) { }

    activate(parms, routeConfig) {
        return this.contactService.getById(parms.id)
            .then(contact => this.contact = contact);
    }
}

Adding get by ID to the Contact Service

The existing ContactService doesn’t provide a function to get a contact by a specific ID so one needs to be added.

The following calls the API in the Contacts project and uses the result to create an instance of a Contact as a promise which is returned to the caller.

getById(id: string): Promise<Contact> {
    return this.http.fetch(id)
        .then(response => response.json())
        .then(contact => new Contact(contact))
        .catch(error => console.log(error));
}

Add a route with a parameter

Next, the router needs to be made aware of the new contact details. Open app.ts inside of the ClientApp/app/components/app folder. This file contains all the routes for the application. The bit we are interested in is the config.map which is an array of routes the application handles. Contact details is a new route which means adding a new object to the config.map array.

{
 route: 'contact-detail/:id',
 name: 'contactdetail',
 moduleId: '../contacts/contactDetail',
 nav: false,
 title: 'Contact Detail'
}

The route is the pattern used to match URLs. In addition, parameters can be used in the form of :parameterName. The above route will handle requests for http://baseurl/contact-detail/{id} where {id} is an ID of a contact. If a route has a parameter it will be made available to the activate function via the parms parameter in the view model.

moduleId is used to locate the view/view model that goes with the route.

nav controls if the route will be included in the routers navigation model. This is used to build the menu in this application. Contact details shouldn’t show in the menu which is why nav is set to false. For more details on Aurelia’s router check out the docs.

Integrating the detail view with the contact list

The contact list view and view model needed changes to support the contact detail page.

View model

The change to the view model was the simplest. A variable for the ID of the select contact was added as well as a function that gets called when a contact is selected. The following is the fully contact list view model.

import { inject } from 'aurelia-framework';
import { Contact } from './contact';
import { ContactService } from './contactService';

@inject(ContactService)
export class ContactList {
    contacts: Contact[];
    selectedContactId: number = null;

    constructor(private contactService: ContactService) {}

    created() {
        this.contactService.getAll()
            .then(contacts => this.contacts = contacts);
    }

    select(contact) {
        this.selectedContactId = contact.id;
    }
}

The changes to the view model were not really required to add the contact detail page, but they are there to show how to setup a click delegate on the view side. In the future, the selected contact could come in handy if the list and details were shown at the same time.

View

On the view, the amount of data being displayed was reduced to show just contact ID and name. A column was added with a link to the details page that is now used to show the rest of information about a contact. The following is the full view.

<template>
    <h1>Contact List</h1>
    <p if.bind="!contacts"><em>Loading...</em></p>

    <table class="table" if.bind="contacts">
        <thead>
        <tr>
            <th>IDs</th>
            <th>Name</th>
            <th></th>
        </tr>
        </thead>
        <tbody>
        <tr repeat.for="contact of contacts" 
          class="${contact.id === selectedContactId ? 'active' : ''" }>
            <td>${contact.id}</td>
            <td>${contact.name}</td>
            <td><a route-href="route: contactdetail; params.bind: {id:contact.id}" click.delegate="select($contact)">
                  Details
                </a>
            </td>
        </tr>
        </tbody>
    </table>
    <hr />
</template>

click.delegate=”select($contact)” will cause the select function of the view model to be called when the associated element clicked and passes the relevant contact object. The docs go into more depth on when to use delegates vs triggers.

The details link contains a lot of concepts. route-href is binding the anchor to Aurelia’s router.

route: contactdetail is telling the router which route to load.

params.bind: {id:contact.id} is telling the link to pass the contact’s ID to through the router to the view model that is being loaded. The following is the activate function of the contact detail view model as a reminder of the parameter’s usage.

activate(parms, routeConfig) {
    return this.contactService.getById(parms.id)
        .then(contact => this.contact = contact);
}

Wrapping up

This post cover a lot of topics, but they were all things I had to review in the course of adding contact details. My hope is this post will shortcut your own research and get you back to your task at hand. The finished code can be found here.

Leave a comment with any thoughts and/or questions.

Aurelia – Router links, click delegate, routing parameters 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 JavaScriptServices: Call to Node module failed

This is going to be a quick post on how to solve an error I go on a new Aurelia project created using JavaScriptServices. For a walk though of creating a project using JavaScripServices check out this post.

The problem

The project got created and would build with no issues, but when I tried to run it I got the following error.

Call to Node module failed with error: Error: Cannot find module ‘./wwwroot/dist/vendor-manifest.json’

The fix

After a little bit of searching I came across this issue on the JavaScriptServices repo with the same error. One of the comments on the issue suggested running the following command from a command prompt in the same directory as your project.

webpack --config webpack.config.vendor.js

After running that command everything worked like a charm! It is worth noting that the command above can be found in project.json in the scripts prepublish section. From the little bit of reading I did it looks like this command should be rerun anytime a new vendor dependency is added.

JavaScriptServices

I can’t get over how awesome JavaScriptServies is. Steve Sanderson (and team) have done an amazing job. Even with this little hiccup I got this new project up and running 10 times faster than I would have otherwise. It is also going to give me a push to look into webpack.

Aurelia with JavaScriptServices: Call to Node module failed Read More »

Angular 2 with ASP.NET Core using JavaScriptServices

This was going to be the fist in a series of posts covering getting started using the RTM versions of ASP.NET Core and Angular 2 together which was going to follow a similar path as the series on Aurelia and ASP.NET Core the first entry of which can be found here.

In the process of writing this post I was reminded of JavaScripServices (they recently added Aurelia support!) and will be using it to get this project up and running instead of doing the work manually.

The code found here can be used as a starting point. The repo contains a solutions with an ASP.NET Core API (Contacts) project and a MCV 6 (Aurelia) project. This post will be add a new MVC 6 project for Angular 2.

JavaScriptServices introduction

JavaScriptServices is an open source project by Microsoft for ASP.NET Core developers to quickly get up and running with one of many JavaScript front ends. The following is their own description.

JavaScriptServices is a set of technologies for ASP.NET Core developers. It provides infrastructure that you’ll find useful if you use Angular 2 / React / Knockout / etc. on the client, or if you build your client-side resources using Webpack, or otherwise want to execute JavaScript on the server at runtime.

The great thing about using the generator that JavaScriptServcies provides is they handle the integration between all the different tools which can be challenging to get right on your own without a lot of time and research.

Project creation

First step is to install the Yeomen generator via npm using the following command from a command prompt.

npm install -g yo generator-aspnetcore-spa

When installation is complete create a new directory call Angular for the project. In the context of the repo linked above this new directory would be in Contact/src at the same level as the Aurelia and Contacts folders.

Open a command prompt and navigate to the newly created directory and run the following command to kick off the generation process.

yo aspnetcore-spa

This will present you will a list of frameworks to choose from. We are going with Angular 2, but Aurelia, Knockout, React and React with Redux are also available.

yoangular2

Hit enter and it will ask for a project name which gets defaulted to the directory name so just hit enter again unless you want to use a different name. This kicks off the project creation which will take a couple of minutes to complete.

Add new project to existing solution

To include the new Angular project in an existing solution right click on the src folder in the Solution Explorer and select Add > Existing Project.

addexisitingproject

This shows the open file dialog. Navigate to the directory for the new Angular project and select the Angular project file.

addexisitingprojectangular

Wrapping up

Set the Angular project as the start up project and hit run and you will find yourself in a fully functional Angular 2 application. It is amazing how simple JavaScriptServices makes getting started with a new project.

The tool setup seems to be one of the biggest pain points with any SPA type JavaScript framework. Aurelia is a little friendlier to ASP.NET Core out of the box than Angular 2, but it still isn’t the simplest process ever. JavaScriptServices is one of those thing I wish I had tried out sooner.

In the near future I am going to redo the Aurelia project in this solution using JavaScriptServices. From there I will come back to the Angular project created in this post and integrate it with the Contact API used in the existing Aurelia application.

Completed code for this post can be found here.

Angular 2 with ASP.NET Core using JavaScriptServices Read More »

Migration from ASP.NET Core 1.0.x to 1.1

UPDATE: For a guide dealing with the conversion to csproj/Visual Studio 2017 check out this post.

On November 16th .NET Core 1.1 was released including ASP.NET Core 1.1 and Entity Framework 1.1. Each of the links contain the details of what was including in the 1.1 release. Unlike some of the previous migrations this is pretty simple.

I will be using my normal ASP.NET Basics solution for this upgrade. The examples will be out of the Contacts project. This post is coming out of order so the repo that goes with this post will contain some items not covered in posts yet. The starting point of the repo can be found here.

Installation

Make sure you already have Visual Studio 2015 Update 3 installed with .NET Core 1.0.1 tools Preview 2 installed. If not use the previous links to install the needed versions. Next head over to the download page for .NET Core and under All downloads and select Current and SDK and select the download for your OS.

downloaddotnet

Another option is to install Visual Studio 2017 RC which can be found here.

Project.json

Project.json is the file that contains all the versions of assembles used by the application. A couple of items need to edited by hand and the rest can be updated using NuGet UI or you can change them all by hand if you like.

First the by hand items. The platform version needs to be updated to 1.1.

Before:
"Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    }

After:
"Microsoft.NETCore.App": {
      "version": "1.1.0",
      "type": "platform"
    }

The second by hand item is the net core app version in the frameworks section.

Before:
"frameworks": {
  "netcoreapp1.0": {
    "imports": [
      "dotnet5.6",
      "portable-net45+win8"
    ]
  }

After:
"frameworks": {
  "netcoreapp1.1": {
    "imports": [
      "dotnet5.6",
      "portable-net45+win8"
    ]
  }

Here is the resulting dependencies and tools sections.

"dependencies": {
  "Microsoft.NETCore.App": {
    "version": "1.1.0",
    "type": "platform"
  },
  "Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
  "Microsoft.AspNetCore.Diagnostics": "1.1.0",
  "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.1.0",
  "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.1.0",
  "Microsoft.AspNetCore.Mvc": "1.1.0",
  "Microsoft.AspNetCore.Razor.Tools": {
    "version": "1.1.0-preview4-final",
    "type": "build"
  },
  "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
  "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
  "Microsoft.AspNetCore.StaticFiles": "1.1.0",
  "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
  "Microsoft.EntityFrameworkCore.SqlServer.Design": {
    "version": "1.1.0",
    "type": "build"
  },
  "Microsoft.EntityFrameworkCore.Tools": {
    "version": "1.0.0-preview3-final",
    "type": "build"
  },
  "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
  "Microsoft.Extensions.Configuration.Json": "1.1.0",
  "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
  "Microsoft.Extensions.Logging": "1.1.0",
  "Microsoft.Extensions.Logging.Console": "1.1.0",
  "Microsoft.Extensions.Logging.Debug": "1.1.0",
  "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
  "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0",
  "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
    "version": "1.1.0-preview4-final",
    "type": "build"
  },
  "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
    "version": "1.1.0-preview4-final",
    "type": "build"
  },
  "BundlerMinifier.Core": "2.2.301"
},

"tools": {
  "BundlerMinifier.Core": "2.2.301",
  "Microsoft.AspNetCore.Razor.Tools": "1.1.0-preview4-final",
  "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final",
  "Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final",
  "Microsoft.Extensions.SecretManager.Tools": "1.1.0-preview4-final",
  "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
    "version": "1.1.0-preview4-final",
    "imports": [
      "portable-net45+win8"
    ]
  }
}

Make note that using the NuGet UI will update the dependencies but not the tools section. For some reason the tools section doesn’t seem to have intellisense so I ended up searching the NuGet site to find the new versions. If you do end up changing the tooling version I recommend doing a dotnet restore in the project directory from the command prompt to ensure the proper versions get downloaded.

Wrapping up

As I said this was a really pain less migration. Make sure you check out the release pages ( .NET Core 1.1, ASP.NET Core 1.1 and Entity Framework 1.1) for the details on what has changed. For example ASP.NET Core has gotten significant performance increases with this release as well as URL Rewriting Middleware and Response Caching Middleware.

It has been less than six months since the initial release of ASP.NET Core until the 1.1 release which a huge increase in the pace of releases compared regular ASP.NET. From what I have see this is a pace the team will continue. Check out the roadmap for a preview of things coming in 1.2.

The code in its final state can be found here.

Migration from ASP.NET Core 1.0.x to 1.1 Read More »

Cross-Origin Resource Sharing (CORS) in ASP.NET Core

Cross-Origin Resource Sharing (CORS) deals with sharing of restricted resources requested from outside the domain which made the request. Check out this Wikipedia article for a good over view of the subject.  If you read the post on Aurelia with an ASP.NET Core API then you might recall that cross-origin requests had to be enabled to allow the front end project to communicate with the API project.

When working on the post mentioned above I only spent enough time on the CORS options in ASP.NET Core to get the sample up and running. This post is going to expand on the path I used to get my sample working and explore some of the options ASP.NET Core offers. The official ASP.NET docs were very helpful in this exploration.

Starting point

In the API project the following was added in the Configure function of Startup in to allow any request regardless of headers, method or origin.

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

Limiting CORS

The above leaves the site wide open for cross-origin requests. Unless you have a need to allow any request it seems like a good idea to limit CORS. Keep in mind I am pretty new to the subject and my sure there are many nuances that will need to play into a live CORS strategy. For example the following limits CORS request to the two domains listed and only allows GET and POST.

app.UseCors(builder =>
    {
        builder.WithOrigins("http://google.com", "http://elanderson.net")
               .WithMethods("GET", "POST")
               .AllowAnyHeader();
    }
);

Note that origins are identified by scheme, host and port all being the same. For example all of the following would be considered different origins.

URLs with different origins
http://google.com
https://google.com
http://www.google.com
https://www.google.com
http://google.com:5000
https://google.com:5000
http://google.com:6000
https://google.com:6000
http://bing.com

Set CORS on a Controller or Action

MVC doesn’t force the whole site to use the same CORS settings. Just like with authorization CORS can be set by Controller or Action. To use this style of CORS ConfigureServices function of the Startup class needs to add CORS as a service and setup one or more policies. The name of the policy will be used with EnableCores attribute to specify where the policy is applied.

In ConfigureServices add app.AddCors which will allow additions of policies and make the available to controllers and actions. The following example adds an “AllowGoogle” CORS policy that allows http://google.com with any header and any method.

services.AddCors(options =>
{
    options.AddPolicy("AllowGoogle",
        builder => builder.WithOrigins("http://google.com")
                          .AllowAnyHeader()
                          .AllowAnyMethod());
});

Then to apply this policy to a controller or an action add the EnableCors attribute. The following example is applying “AllowGoogle” policy to the whole HomeController.

[EnableCors("AllowGoogle")]
public class HomeController : Controller

Now if you want to exempt the Index from the “AllowGoogle” CORS policy use the DisableCors attribute.

[DisableCors]
public IActionResult Index()

Wrapping up

I am sure the CORS subject goes much deeper than what I covered today, but I wanted to share what I have learned so far as it applies to ASP.NET Core. If you have more resources or have something to add please leave a comment.

Cross-Origin Resource Sharing (CORS) in ASP.NET Core Read More »

Aurelia with ASP.NET Core: Host Aurelia from a Controller

This is the forth entry in a series using Aurelia and ASP.NET Core together. Each post builds on the previous and all the code is available on Github.

Part 1 – Add Aurelia to an ASP.NET Core Project
Part 2 – Aurelia with an ASP.NET Core API
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 (this post)
Github repo with the code for all of the parts with a release to go with each post

The goal

So far the Aurelia application in this series has existed outside of the the ASP.NET Core application. This post is going move the Aurelia application to be hosted by a MVC controller and a razor view. This would allow an existing application to slowly be ported to Aurelia or allow portions of an application to be replaced by Aurelia as it made sense, etc.

The controller

The controller isn’t going to be doing much other than returning a view that contains the entry point for the Aurelia application. This example will be using a new Aurelia  action on the HomeController.

public IActionResult Aurelia()
{
    return View();
}

The view

Next create a view in the Views/Home folder named Aurelia.cshtml to match the name of the action added to the HomeController above. Right click on the Home folder and select Add > New Item.

addnewitem

This will show the Add New Item dialog. Using the search in the upper right corner serach for MVC and select MVC View Page. Enter Aurelia.cshtml as the name and click Add.

Enter the following in the newly created file.

<div aurelia-app="main">
    <script src="/scripts/vendor-bundle.js" data-main="aurelia-bootstrapper"></script>
</div>

This code defines a div that will host an Aurelia application named main.

Add a link to the Aurelia application

Inside of the Views/Shared folder open _Layout.cshtml which is where the MVC application’s navigation bar is defined. Locate the navigation bar code and add a list item and link that points to the HomeController Aurelia action defined above. The following is the full navigation bar for the MVC application including the new link for Aurelia.

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
        <li><a asp-area="" asp-controller="Home" asp-action="Aurelia">Aurelia</a></li>
        <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
        <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
    </ul>
</div>

Adjust Aurelia’s baseUrl

Finally inside the aurelia_project folder open aurelia.json and adjust the baseUrl property inside the targets section to look for the scripts folder to be up one directory. This is required now with the Aurelia application being hosted inside the HomeController which will cause the Aurelia application to look for its scripts in the Home/Scripts folder instead of the site’s main scripts folder. If you are going to have multiple Aurelia applications per MVC application then you may need to take a different path on this section.

Before:
"build": {
  "targets": [
    {
      "id": "aspnetcore",
      "displayName": "ASP.NET Core",
      "output": "wwwroot\\scripts",
      "baseUrl": "scripts"
    }
  ]

After:
"build": {
  "targets": [
    {
      "id": "aspnetcore",
      "displayName": "ASP.NET Core",
      "output": "wwwroot\\scripts",
      "baseUrl": "../scripts"
    }
  ]

Wrap up

Run the application and click the Aurelia link in the navigation bar and the Aurelia application from last week will run, but now it will still have the navigation bar from the MVC application showing. The index.html file located in the wwwroot folder that was previously used to host the Aurelia application can be deleted.

The code associated with this post can be found here.

Aurelia with ASP.NET Core: Host Aurelia from a Controller Read More »

Aurelia with an ASP.NET Core API: Modeling and Displaying Data in Aurelia

This is the third entry in a series using Aurelia and ASP.NET Core together. Each post builds on the previous and all the code is available on Github.

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

Starting point

Starting with the code from last weeks post we have a single solution with two projects. The Contacts project contains a basic razor UI for CRUD operations related to contact management as well as an API to provide that contact data to other applications.

The Aurelia project is a MVC application with Aurelia. At the moment the MVC and Aurelia applications don’t interact. In its current state the Aurelia application will connect to the Contacts API, download a list of contacts, and display the names of the contacts.

The goal

This post will cover taking the data from the Contacts API and mapping it to a JavaScript model class. Next the existing display of contacts will be removed and replaced with a contact list component.

Create a model

Create a contacts folder inside the src folder of the Aurelia project. Next add a contact.js file. This will be the model of a contact in the system. At the moment it only contains a constructor and a getAddress function. getAddress is just a demonstration of the model providing some functionality and not just being a data container.

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

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

The Contact class ends up with all the properties of the data that was past to the constructor. In this case is all the properties from the Contact class in the Contact project. Coming from a mostly C# background the dynamic nature of JavaScript takes a little bit of getting used too.

 File naming an view/view model location

I hit a problem with how my files were named and Aurelia’s view/view model location strategy. I haven’t found a list of the conventions, but here is what I found playing around based on a view model named ContactList.

Filename Element Located
ContactList contact-list No
Contact-List contact-list No
Contact-List Contact-List No
contactlist contactlist No
contact-list contact-list Yes

Had the class name been Contactlist then the contactlist in the list above would have worked. For more information on how view are located check out this section of the Aurelia documentation.

Renaming for consistency

Based on research into why a view was not being located I am doing a bit of reorganizing in the project. All the contact related files are moving to a new contacts folder and the contactService.js is being renamed to contact-service.js. This is following the idea of organizing code by feature instead of type of file.

Update the Contact Service to use the new Contact class

In the contacts folder open the contact-service.js file. Next add an import for the Contact model class.

import { Contact } from './contact';

Next to the GetAll function add a line to convert the data to a Contact.

GetAll() {
   return this.http.fetch('')
        .then(response => response.json())
        .then(contacts => Array.from(contacts, c => new Contact(c)))
        .catch(error => console.log(error));
}

Here is the complete contact-service.js file.

import { HttpClient } from 'aurelia-fetch-client';
import { Contact } from './contact';

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())
            .then(contacts => Array.from(contacts, c => new Contact(c)))
            .catch(error => console.log(error));
    }
}

To verify the returned results are actually using the Contact model class change the call in App.js to use the getAddress function instead of just printing the contact names.

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

Run the application and it will print customer addresses. Note that the URL for the Aurelia application is http://localhost:37472/index.html.

Adding a contact list

Add two new files to the contacts folder for contact-list.html and contact-list.js which will result in the following structure.

contactrenames

The view model

contact-list.js is the view model for the contact list and will handle calling the ContactService to get a list of contacts to display. The contact service needs to be imported and injected via the constructor. Additionally the constructor is setting up an array that will be used to store the contacts after they are retrieved.

The call to the contact service is handled in the created function which is automatically called as part of Aurelia’s component lifecycle. For more information on the component lifecycle see the official documentation here. The following is the full definition of the ContactList view model class.

import { ContactService } from './contact-service';

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

    constructor(contactService) {
        this.contactService = contactService;
        this.contacts = [];
    }

    created() {
        this.contactService.GetAll()
            .then(contacts => this.contacts = contacts);
    }
}

The view

contact-list.html is the view that Aurelia will map and use with contact-list.js. As before this view is going to be very basic to keep the noise down. The view is a template with an unordered list of contact names and their addresses.

<template>
    <ul>
        <li repeat.for="contact of contacts">
            <h4>${contact.name}</h4>
            <p>${contact.getAddress()}</p>
        </li>
    </ul>
</template>

The repeat.for tells Aurelia to output a list item for each contact found in the contacts property of the view model. ${contact.name} is a one way binding to the name property of the current contact. Also notice ${contact.getAddress()} which is one way binding the result of a function from the Contact model class.

Displaying a component

Now the component needs to be displayed. For simplicity the contact list will be shown directly from the main application view (app.html). The sample from last week will need to be cleared out before adding the contact list view. In the end the view should contain the following.

<template>
    <require from="./contacts/contact-list"></require>
    <h1>App</h1>
    <contact-list></contact-list>
</template>

require from is importing the contact list and then the contact-list tag determines where the contact list will show. Aurelia makes all components available in this manner. They just needs to be required in to be used as a tag.

Finally make sure to clear out app.js if using the sample from last week as retrieving contact list data has been moved to the contact list view model.

export class App {
}

When the application needs it the App class is where the application level router would go.

Wrap up

Aurelia is always a pleasant surprise after being away from it for awhile. After getting project setup and conventions down it is always pleasant to use. The documentation is very good for the most part. As you can tell from this post I had some trouble with conventions which is something I wish was covered better in the docs, and if it is and I just missed it please leave a comment.

The code associated with this post can be found here.

Aurelia with an ASP.NET Core API: Modeling and Displaying Data in Aurelia 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 »