Great Angular, ASP.NET Core Starter Templates

Great Angular, ASP.NET Core Starter Templates Title

This post exists to provide hope. After the somewhat hesitant reaction to last week's webpack post, this post highlights two great Angular and ASP.NET Core starter templates. These starter projects not only contain configurations for webpack 1 and webpack 2, there are a ton of other Angular and ASP.NET features implemented for you.

ASP.NET Core Template Pack

ASP.NET Core Template Pack - Angular Starter

The first project template to note comes from the ASP.NET Core Template Pack by Mads Kristensen. The template pack is a Visual Studio Extension containing multiple templates for ASP.NET Core. The collection includes a helpful Angular template.

Key Features

The hallmark feature of the template is Angular Universal. This framework enables server-side Angular rendering when the application is initially requested from the server. Angular Universal decreases the initial page load time by rendering the first request on the server instead of requiring the client to wait for the application to download before rendering. Subsequent route changes are all rendered client-side. For any application that requires minimum load times, this framework is a must-see.

The template also uses webpack version 1. For anyone working on integrating webpack into their applications, every example helps. This template doesn't use the latest loaders that the folks on the Angular side of the community are using. It does however accomplish the primary goal by compiling combined scripts. And being that it's using Angular Universal, there are webpack configurations for both the client application and the server rendering portion.

The template also implements webpack's hot module replacement feature. This is a development feature where the client-side code is replaced in the browser via a WebSocket when the source module is edited on the file system. If you've ever used a development server with automatic refresh like Browser Link or Browsersync, then it's like that – except without the full page refresh. You should check out the template just to try out this feature – you may never go back.

The previously mentioned features are configured with the help of Steve Sanderson's ASP.NET Core JavaScript Services. This library is part of ASP.NET Core on GitHub and provides useful integrations for single-page application (SPA) frameworks including Angular. The template includes simple, foundational examples for routing and data access as well as Docker container configuration.

Gotchas

Currently, if you are looking for the very latest in front-end Angular features, this template doesn't have them. It's using webpack version 1 versus webpack version 2 and doesn't include all of the niceties that have been introduced with newer webpack loaders such as awesome-typecript-loader and angular2-template-loader.

Also, if you see an error like this when starting the template, it means you have to specify a prior version of ASP.NET using the global.json file.

Template Error

You can read more about the solution on GitHub.

Bottom Line

This is a stable template that highlights the main integration points between ASP.NET Core and Angular. For now, it might not have the most up-to-date client-side features but you can imagine these will come as the tooling comes to a final release (or when we all submit pull requests). Being a Visual Studio extension, it is optimized for the Visual Studio IDE and it provides a nice starting point.

To view the source for this template, check out its GitHub repository.

ASP.NET Core & Angular2 Universal Starter (Angular2Spa)

ASP.NET Core & Angular2 Universal Starter Diagram

This might be the best Angular on ASP.NET Core template available right now. It's actively developed by a member of the Angular Universal team, Mark Pieszak.

In fact during the course of writing this review, he fixed an issue that I was experiencing while working with the template for this article. The template contains some of the latest techniques and frameworks for building Angular applications on ASP.NET or otherwise.

Key Features

You can think of this project as a superset of the template currently in the ASP.NET Core Template Pack. It has the same base level of features and then adds on top of it. This template works in Visual Studio. It also contains configuration files to run in Visual Studio Code, complete with key bindings to initialize the dotnet build. It even uses the newer ASP.NET Core 1.1 assembly versions.

For the front-end tooling, the template uses webpack version 2 including many new loader patterns that you find in the Angular documentation. The example also makes use of an RxJS-based, Redux-like store via the NgRx library.

To help keep your code styles on par, this template uses codelyzer. Built on top of TSLint, codelyzer provides linting for TypeScript as well as the Angular Style Guide conventions.

Finally, this template configures unit testing with Karma and Jasmine integrated with webpack. It also includes end-to-end (E2E) tests using Protractor. These configurations alone can save you a dozen hours versus configuring yourself.

Gotchas

Certainly check out the README file for this project. It has a lot of great information on how to use Angular with or without this template and highlights areas where you may otherwise stumble. One other word of caution – this template leans on the bleeding edge so you may find some instability along the way. The maintainer so far seems to do a nice job keeping up with any logged issues.

Bottom Line

This is a must-see and must-watch starter template for ASP.NET developers using Angular. There is nothing more to say, take a look for yourself.

Final Thoughts

The Angular and ASP.NET frameworks are both evolving at a rapid pace and it can be difficult to keep current with the changes. These templates can help you start coding quickly and help you incorporate new technologies and patterns as they are published.

These are two of the best and more noteworthy starter templates for Angular and ASP.NET. Give them a try and share your thoughts below. If there are any other starter templates you find helpful, please let everyone know in the comments.

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 6

Angular2, ASP.NET Core, Visual Studio Code, Part 6

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is the last in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

This article discusses an important part of the integration between client and server – routing. Angular 2 has its own router and so does ASP.NET Core. In the following sections you learn to setup routing in Angular 2 and then how to support the Angular 2 routing with ASP.NET Core.

This post addresses the high-level concerns of integrating these two routing systems. For more information on the individual routing features for each framework, read about Angular 2 routing here and ASP.NET Core routing here.

.NET Core SDK Preview 3: This tutorial uses .NET Core SDK Preview 3 which is available on GitHub. This version includes 'alpha' support for MSBuild-based projects that use .csproj configuration instead of project.json configuration. Microsoft announced that MSBuild is the common project configuration for .NET Core based projects going forward. By using MSBuild, the goal is to better prepare you for future versions of the tooling.

If you would like to jump straight to the code, it's all on GitHub.

Refactor to Multiple Components

In order to implement routing for Angular 2, you need to have multiple components in the project.

Move the contents of AppComponent to a new component called PairingComponent which is responsible for pairing Sriracha with foods.

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-pairing',    
    template: `
        <h2>Pairing</h2>
        <input type="text" [value]="food" (input)="foodInput($event)"/>        
        <p>Sriracha sauce is great with {{ food }}</p>
    `,
})
export class PairingComponent { 
    food = 'kielbasa';

    foodInput(event: Event) {
        const target = event.target as HTMLInputElement;
        this.food = target.value;
    }
}

The AppComponent becomes the application shell including the navigation. For now, the PairingComponent is rendered directly in the AppComponent template.

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: `
        <nav>
            <a href="/pairing">Pairing</a> | 
            <a href="/about">About</a>            
        </nav>
        <my-pairing></my-pairing>
    `,
})
export class AppComponent { }

Also, create a third component called AboutComponent which serves as a second view.

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-about',    
    template: `
        <h2>About Sriracha</h2>

        <p>This is what Wikipedia says about <a href="https://en.wikipedia.org/wiki/Sriracha_sauce_%28Huy_Fong_Foods%29">Sriracha sauce</a>:</p>

        <blockquote>It can be recognized by its bright red color and its packaging: a clear plastic bottle with a green cap, text in Vietnamese, English, Chinese, French, and Spanish, and the rooster logo. David Tran was born in 1945, the Year of the Rooster...<blockquote>
    `,
})
export class AboutComponent { }

Finally, you declare all of these components in the AppModule.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { PairingComponent } from './pairing.component';
import { AboutComponent } from './about.component';

@NgModule({
    bootstrap: [ AppComponent ],
    imports: [ 
        BrowserModule,
    ],
    declarations: [ 
        AppComponent, 
        PairingComponent, 
        AboutComponent, 
    ],
})
export class AppModule { }

The app directory now looks like this:

component folder structure

Run your application to see the new navigation.

Navigation Screenshot

Configure the Angular 2 Router

To configure the AppModule routes, import RouterModule and Routes from @angular/router. The Routes type is an array of Route objects used to define the routes.

When navigating to http://localhost:5000/pairing the application should show the PairingComponent. When navigation to http://localhost:5000/about the application should show the AboutComponent. There is also a third scenario. When navigating to the root of the application, http://localhost:5000/, the application should redirect to http://localhost:5000/pairing as the default.

This is what the Routes array looks like:

const routes: Routes = [
  { path: '', redirectTo: '/pairing', pathMatch: 'full' },
  { path: 'pairing',  component: PairingComponent },
  { path: 'about', component: AboutComponent },
];

The pathMatch property must be set for all redirects. In this case, the value 'full' denotes that the redirect should occur when the path is at the application root or is otherwise empty ('').

Next, register these routes with the RouterModule and register the RouterModule with the AppModule.

This is the final code for the AppModule:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';

import { AppComponent } from './app.component';
import { PairingComponent } from './pairing.component';
import { AboutComponent } from './about.component';

const routes: Routes = [
  { path: '', redirectTo: '/pairing', pathMatch: 'full' },
  { path: 'pairing',  component: PairingComponent },
  { path: 'about', component: AboutComponent },
];

@NgModule({
    bootstrap: [ AppComponent ],
    imports: [ 
        BrowserModule,
        RouterModule.forRoot(routes),
    ],
    declarations: [ 
        AppComponent, 
        PairingComponent, 
        AboutComponent, 
    ],
})
export class AppModule { }

Finally, the Angular router depends on a base element with href defined. You add this in the head of index.html so that Angular can update the browser's address bar correctly. This is the updated index.html code:

<!DOCTYPE html>
<html>

<head>
    <title>Angular 2, ASP.NET Core Starter</title>
    <base href="/">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>

    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>

    <script src="systemjs.config.js"></script>
    <script>
        System.import('app').catch(function(err){ console.error(err); });
    </script>
</head>

<body>
    <my-app>Loading...</my-app>
</body>

</html>

Configure the Navigation

The last step to configure the Angular routing is to configure the navigation to utilize the routes. To accomplish this, you modify the AppComponent template in two significant ways.

First, instead of including the my-pairing element in the AppComponent template, replace it with the router-outlet element. This is a placeholder where the router renders the component matching the current route.

Finally, you replace the href attribute with the routerLink attribute. This is a directive instructing Angular to register the click with the router instead of the default href behavior.

The final code for the AppComponent looks like this:

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: `
        <nav>
            <a routerLink="/pairing">Pairing</a> | 
            <a routerLink="/about">About</a>            
        </nav>
        <router-outlet></router-outlet>
    `,
})
export class AppComponent { }

At this point, run the application using Ctrl+Shift+B and start the browser using npm run chrome which you configured in part 5. Notice how the application defaults to the /pairing URL. Clicking on the link loads the appropriate component for that specific URL.

Working Angular 2 Routes

There's still one problem. When you go directly to a route URL like http://localhost:5000/about from the browser's address bar, you see a 404 error. This is a result of the fact that even though Angular knows how to reconcile this URL, the server does not.

In the next section, you configure the ASP.NET MVC routes to return the Angular application when it doesn't recognize the route.

Add ASP.NET Routing

In order to configure ASP.NET routing, you must install the ASP.NET MVC package. Add this PackageReference to the .csproj file and then run dotnet restore from the terminal.

<PackageReference Include="Microsoft.AspNetCore.Mvc">
    <Version>1.1.0</Version>
</PackageReference>

Once the package is installed, create a directory at the root of your project called Controllers. Inside this directory, create a file called HomeController.cs. In this file, create a HomeController class which inherits Controller. This is the code.

using System.IO;
using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller
{
    public IActionResult Index()
    {
        var fileName = "index.html";
        var contentType = "text/html";

        string filePath = Path.Combine(Directory.GetCurrentDirectory(), fileName);
        string fileContents = System.IO.File.ReadAllText(filePath);

        return Content(fileContents, contentType);
    }
}

In ASP.NET MVC, controllers are where a request is processed and a response is constructed. In this controller, the Index method reads the index.html file containing the Angular application and returns the file contents as a text/html response to the browser. This is essentially the same response that the browser receives when requesting index.html directly. Once the application is loaded into the browser, the Angular router takes over.

In order for the HomeController to do its thing, you must configure the ASP.NET MVC router to direct all of the incoming requests to the Index method.

In the Startup.cs file, you have to add a couple new configurations. First, ASP.NET MVC is configured as a service which requires the Startup class to implement a ConfigureServices method. Also, you configure the routes in the existing Configure method. The new Startup.cs code looks like this:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseDefaultFiles();
        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{*url}",
                defaults: new { controller = "Home", action = "Index" });
        });
    }
}

The MapRoute method takes a configuration object. The template field defines the URL pattern that matches the route. Because there is only one variable defined in the template and it uses the asterisk, this route essentially handles all requests that haven't already been handled by the UseDefaultFiles or UseStaticFiles middleware. Furthermore, the defaults field directs all of these requests to the HomeController and it's Index action method.

At this point, run your application. In the browser, go directly to http://localhost:5000/about and you will see that the application loads from the server. Once the Angular application loads, it applies the correct route on the client.

Routing Integration

The End

This brings the final part of this Angular 2, ASP.NET Core, and Visual Studio Code journey to a close. You have learned a lot about configuring these frameworks and tools to work together. You've learned your way around Visual Studio code. You configured an Angular 2 and ASP.NET Core application so that both frameworks play well together. You created a basic Angular 2 application and automated tasks with npm and Visual Studio Code.

But you have only scratched the surface. This is just the beginning. What was your favorite discovery? Which topics are you most interested in learning about more? Leave a comment below and have fun with your new tools!

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 5

Angular2, ASP.NET Core, Visual Studio Code, Part 5

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is part five in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

This post is all about automating common development tasks with npm scripts and Visual Studio Code. You learn how to install and clean dependencies, launch browsers, automatically rebuild your .NET code, and setup a build task in Visual Studio Code.

Mac and Linux Users: The commands in this article related to cleaning dependencies and launching browsers are specific to Windows. You can still use npm scripts on Mac and Linux by replacing the Windows commands with those for your environment. Details for specific commands are found readily through your favorite search engine.

.NET Core SDK Preview 3: This tutorial uses .NET Core SDK Preview 3 which is available on GitHub. This version includes 'alpha' support for MSBuild-based projects that use .csproj configuration instead of project.json configuration. Microsoft announced that MSBuild is the common project configuration for .NET Core based projects going forward. By using MSBuild, the goal is to better prepare you for future versions of the tooling.

If you would like to jump straight to the code, it's all on GitHub.

Note: If you have been following along with the series from the beginning, you might have noticed that this post was previously listed as being about Browser Link. Unfortunately, this feature still appears to be heavily tied to the full Visual Studio IDE. The tooling story for ASP.NET Core and Visual Studio Code continues to develop and you can expect more posts on these topics as additional tooling becomes available.

NPM Scripts

For this walkthrough, you are continuing from the npm script you built in part 3. While Visual Studio Code supports a variety of automation tooling, npm scripts are a discoverable and simple way to automate tasks for your project.

The scripts are all located in the package.json file under the "scripts" property. At this point in the walkthrough, this is the current version:

"scripts" : {
    "start": "tsc && concurrently \"tsc -w\" \"dotnet run\" "
},

This script compiles the TypeScript files and then runs the TypeScript compiler in watch mode alongside running the ASP.NET application. You invoke it by entering npm start in the terminal.

Notably, npm has built-in commands as well as custom scripts. For instance, start is a built-in command. You invoke it by entering npm start. However, if you take the same script and call it gyro, it would not be recognized by entering npm gyro because it is not a built-in command. You instead enter npm run gyro into the command line to invoke that script.

It's important to understand that the built-in commands sometimes have special behavior. You can see the full list supported by your version of npm by entering npm -h in the terminal and you can read more about these commands in the documentation.

Installing Dependencies

Part 3 of this series describes how to setup a package.json file and shows how to use npm install to download the dependencies from npm. In part 2, it similarly describes using dotnet restore to do the same thing for .NET Core dependencies. Instead of using these two commands, what if you only had to remember one to install all the dependencies in your project?

The npm install command is one of the npm commands with special behavior. You configure an npm script named install but the commands get executed after the default npm install command has finished. The is the perfect place to call dotnet restore. Add the following to the scripts property:

"scripts" : {
    // ... 
    "install": "dotnet restore"
},

Now when you enter npm install in the terminal, the dotnet dependencies install as well.

Cleaning the Project

In addition to installing dependencies, you should be able to easily delete out-of-date dependencies. Essentially, you need a set of scripts to delete the downloaded packages and build artifacts from the project directory. These commands work well on Windows for this purpose:

"scripts" : {
    // ... 
    "clean": "npm run clean:dotnet && npm run clean:npm",
    "clean:dotnet": "npm run clean:bin && npm run clean:obj",
    "clean:bin": "del /q .\\bin\\*.* && for /d %i in (.\\bin\\*.*) do @rmdir /s /q \"%i\" ",
    "clean:obj": "del /q .\\obj\\*.* && for /d %i in (.\\obj\\*.*) do @rmdir /s /q \"%i\" ",
    "clean:npm": "del /q .\\node_modules\\*.* && for /d %i in (.\\node_modules\\*.*) do @rmdir /s /q \"%i\" "
},

Notice the clean script is composed of multiple npm scripts. When calling multiple commands, concatenate them with two ampersands (&&). The bulk of the work is done with the clean:bin, clean:obj, and clean:npm scripts which delete the contents of the bin, obj, and node_modules folders respectively. Because these commands delete only the contents, they can be called repeatedly without throwing an error.

Also notice that calling these scripts requires the run command. For instance, to call the clean script you type npm run clean in the terminal.

With these scripts, whenever you get an updated version of the repository, type npm run clean follow by npm install in the terminal and you have a fresh copy of the required npm and .NET dependencies. You might even decide to create a new script that calls them both.

Launching the Browser

Another important development task is opening the browser, sometimes multiple browsers, to test your application. This too, is an automation candidate. Here are three commands for launching different browsers to the application URL:

"scripts" : {
    // ... 
    "edge": "start microsoft-edge:http://localhost:5000",
    "chrome": "start chrome http://localhost:5000",
    "firefox": "start firefox http://localhost:5000"
},

Once added, type npm run chrome in the terminal to startup Google Chrome at the development URL.

Watching ASP.NET Code Changes

If you look at the start script, tsc -w initializes the file watcher for the TypeScript compiler. This command watches the file system for any TypeScript file changes and automatically re-runs the TypeScript build. To duplicate this functionality for C# code, use the dotnet watch command.

The dotnet watch command is a dotnet CLI extension. You reference the tool by putting the following in the project's .csproj file:

<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild2-final"/>
</ItemGroup>

You can now use your new npm install script to restore the .NET dependency or simply run dotnet restore to download the package. Once it's installed, modify the build script to use dotnet watch run instead of dotnet run. This is the full scripts property in the package.json file including the dotnet watch change:

"scripts": {
    "start": "tsc && concurrently \"tsc -w\" \"dotnet watch run\" ",
    "install": "dotnet restore",
    "clean": "npm run clean:dotnet && npm run clean:npm",
    "clean:dotnet": "npm run clean:bin && npm run clean:obj",
    "clean:bin": "del /q .\\bin\\*.* && for /d %i in (.\\bin\\*.*) do @rmdir /s /q \"%i\" ",
    "clean:obj": "del /q .\\obj\\*.* && for /d %i in (.\\obj\\*.*) do @rmdir /s /q \"%i\" ",
    "clean:npm": "del /q .\\node_modules\\*.* && for /d %i in (.\\node_modules\\*.*) do @rmdir /s /q \"%i\" ",
    "edge": "start microsoft-edge:http://localhost:5000",
    "chrome": "start chrome http://localhost:5000",
    "firefox": "start firefox http://localhost:5000"
},

Now you can make changes to your C# code while the application is running and when you save the file, the .NET project rebuilds without any developer intervention.

Key Binding for NPM Start

While npm scripts are already easily accessible through the built-in terminal, Visual Studio Code offers a way to map a build task to a keyboard shortcut.

The default build task key binding is Ctrl+Shift+B and it is configurable. To map the npm start command to this task, begin by pressing Ctrl+Shift+B from anywhere in Visual Studio Code. At this point, Visual Studio Code sees that you are using npm scripts and prompts you to create a tasks.json file within the .vscode directory. Press the Configure Task Runner button to create the file.

Configure Task Runner

Now that the file is created, modify the tasks property to map the npm start script. In addition, set the task's isBuildCommand property to true to associate the task with the build command key binding, Ctrl+Shift+B.

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "npm",
    "isShellCommand": true,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [
        {
            "isBuildCommand": true,
            "taskName": "start",
            "args": ["start"],
            "isWatching": true            
        }
    ]
}

Save the file and try out the new functionality by pressing Ctrl+Shift+B. You should see the application starting in the terminal. To terminate the task, press F1 and find the command to Terminate Running Task.

Terminate Running Task

You can create additional tasks out of the other npm scripts but Visual Studio Code limits you to having one task running at a time. Furthermore because this build task runs in watch mode, it may be running most of the time you are in the editor. Therefore, it makes sense to continue running your other npm scripts from the terminal.

Build Succeeded

You are now equipped to zip through your development workflow using npm scripts and Visual Studio Code tasks. If you're coming from the Visual Studio IDE, this gives you an idea of how to accomplish some of what the full-fledged IDE provides and hopefully further inspires you to customize the tasks that Visual Studio Code enables.

Now that you have gotten a glimpse at what is possible, what other automated functionality would you like to see? How have you configured Visual Studio Code to help you be more productive? Let everyone know in the comments.

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 4

Angular2, ASP.NET Core, Visual Studio Code, Part 4

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is part four in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

In this post, you write a 'Hello World' style Angular 2 application. You are introduced to components, NgModules, and template syntax. The walkthrough discusses how to bootstrap an Angular 2 application in the browser and along the way you learn how to better manage your TypeScript files in Visual Studio Code.

This post scratches the very surface of what Angular 2 offers. It's included in the series for completeness and to offer perspective regarding the framework's fundamental building blocks. It is not intended to replace the excellent documentation that the Angular team has produced. So when you get the chance, please take some time and go through the Angular 2 Tour of Heroes Tutorial to learn about the wider breadth of features available in the framework.

Note: If you have been following along with the series prior to this post being published, there is an update to the Part 3 Angular 2 configuration. Please ensure you have the @types/node package installed in your devDependencies. This typings library contains definitions for the module.id API used in this part of the walkthrough.

If you would like to jump straight to the code, it's all on GitHub.

Define the Root Tag

First, add a custom tag to your index.html file. Angular uses the custom tag as an identifier for where in the document to render the application. Any content between the opening and closing tags is replaced during the bootstrap process, so this is a convenient place to add a loading message or indicator. Within the body of your index.html page, add the custom my-app element:

<body>
    <my-app>Loading...</my-app>
</body>

Your First Component

It's time to create your first Angular 2 component. An Angular 2 component is essentially a JavaScript class adorned with the @Component decorator in which you define a template. The class encapsulates the behavior of the component and the template encapsulates the view. Angular does the work to wire the view to the behavior for you.

Components are the building blocks of your application. At the root of your application, is a component containing other components, composed together to form a user interface. This composition is sometimes called a component tree where the root component contains all of the other components in your application and leaf components represent the re-usable widgets of your application with which the user interacts.

Component tree

Create a file within your application's app directory called app.component.ts. Go head and add this component code:

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: 'Hello, Angular 2 World!',
})
export class AppComponent { }

The @Component syntax is a decorator. This code adorns the AppComponent class and adds metadata information about the class. In this case, it denotes that this class is an Angular 2 component.

The import statement obtains the Component decorater from the @angular/core library. This import statement is an example of node module resolution which you setup in part 3 of this series. The Component decorator sets three properties, moduleId, selector, and template.

The moduleId property, when used, is generally set in this fashion. By setting it to module.id, you are supplying the current ECMAScript 2015 module's URL to Angular. This helps the framework load external templates and styles from the same relative location (URL) as the component's scripts. In this example, the component has no external templates or styles and thus setting moduleId is not required. However you may find it's easier to always set moduleId than to keep track of when you need it and when you don't.

Angular uses the selector property as a CSS selector to query a template finding all the elements that should be initialized as this component. For instance, when you use this component in a view, you define it as <my-app></my-app>. This selector is a tag selector, because it targets elements by tag name. But you can use other CSS selector types. If you prefer to define your components in markup by class (.my-app) or by attribute ([my-app]) simply change the selector accordingly.

The template property is the view or markup rendered for the component. In a moment, you will explore the template syntax more. It's important to note that there are two template-related properties available on the Component decorator: template and templateUrl. The templateUrl property points to a separate file containing the markup. For any template more than a couple lines, creating a separate file and using templateUrl is generally easier. You'll find in Visual Studio Code (and probably many other editors) that having the extra HTML syntax highlighting and auto-complete when writing in a dedicated .html file is more productive.

Finally, the Component decorator annotates the component class definition. The Angular 2 Style Guide recommends suffixing class names with the Angular object type which is why this class is named AppComponent but ultimately you have the freedom to decide which naming convention to use. Notice the class is exported using the export keyword so that it can be consumed in other ECMAScript modules as you will soon see. Finally, this component is very simple with no behavior which is why the class definition doesn't have much code yet.

Your First Angular Module

Angular 2 brings forward the concept of Angular modules from Angular 1.x although in quite a different form. In Angular 2, Angular modules are defined with the NgModule decorator. To distinguish from ECMAScript 2015 (ES2015) modules, this post will refer to them as NgModules.

First, what's the difference between an NgModule and an ES2015 module? You can think of ES2015 modules as encapsulated, reusable units of code whereas NgModules are encapsulated, reusable units of the application. NgModules are composed of ES2015 modules making them a sort of higher-order unit. Again coming from the Angular 1.x world, NgModules are very similar conceptually to angular.module. If you are coming from a C#/.NET background, you can almost think of NgModules as namespaces or assemblies.

Angular requires you to have at least one NgModule in your application. For small applications this may be preferable, but as your code base grows adding additional NgModules may help you reason about the application.

For this example, create one NgModule to house and bootstrap your application. In the app directory, create the app.module.ts file and add this code:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

@NgModule({
    bootstrap: [ AppComponent ],
    imports: [ BrowserModule ],
    declarations: [ AppComponent ],
})
export class AppModule { }

Notice that all the configuration occurs in the NgModule decorator. The bootstrap property is only necessary in this root NgModule. It instructs Angular to examine the existing DOM (parsed from index.html in this case), identifying the elements to replace with the components defined in bootstrap.

The imports property defines any NgModules that are consumed by this NgModule. Being this root NgModule is running in a browser, you must import the BrowserModule. The other NgModules in your application do not need to import that BrowserModule, only the root NgModule.

Finally, you declare all of the Components and Directives that belong to this NgModule in declarations. There are several other important properties with the NgModule decorator so refer to the documentation for more information.

Bootstrap the Application

Angular 2 provides multiple ways to bootstrap your application depending on where it is running (server versus browser) and whether it has been compiled ahead of time (AOT) or not. For this example, use just-in-time (JIT) compilation in the browser with platformBrowserDynamic to bootstrap the AppModule. In your main.ts file, replace the contents with this:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

Save all of your files and start your application. From the terminal (Ctrl+`), type npm start to compile the TypeScript and start your ASP.NET Core application. Then view the application in the browser at http://localhost:5000. You see the message 'Hello, Angular 2 World!'

Hello, Angular 2 World!

Hide Generated TypeScript Files

At this point, you have three TypeScript files in your app directory and also six additional .js and .js.map files generated from the TypeScript build.

TypeScript generated files

Having three of each file name in the explorer pane can make it difficult to find the actual file you need. Furthermore, you don't really need to see the JavaScript and source map files during development. To address this, Visual Studio Code has settings to hide these files in the explorer pane.

There are two options when changing Visual Studio Code settings. The editor allows you to configure settings for your user profile on the development machine. In this way, all of your projects pick up the same settings on that machine but unless you manually back it up, those settings could be lost.

You also have the option to configure settings for your workspace which are easy to save in source control and restored on whichever machine you use. The downside is that they are only applied to that particular project. For this exercise, you are configuring workspace settings.

In the File menu, select Preferences, then click Workspace Settings. This creates a .vscode directory in your application root containing a file named settings.json.

File Menu, Workspace Settings

This file contains a set of matching curly braces. Within those curly braces, begin typing "files.exclude" but press TAB before the closing quote symbol. When you press TAB to trigger autocomplete, the default excluded files and directories are populated.

settings.json auto-complete

To that list of globs, add one to hide the source map files and one to hide the generated JavaScript files. When you are done the configuration looks like this:

{
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/.DS_Store": true,
        "**/*.js.map": true,
        "**/*.js": { "when" : "$(basename).ts" }
    }
}

When you save the file, you see that now only the TypeScript files are visible in the explorer pane.

No TypeScript Generated Files

Template Syntax

To wrap up this Angular example, you explore the Angular 2 template syntax. Open up the app.component.ts file to make changes to this component.

First, add a property to the component class called food and set it to your favorite food. Then, replace the template property with a basic template. Your component should look like the following:

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: `
        <input type="text" [value]="food" />
        <p>Sriracha sauce is great with {{ food }}</p>
    `,
})
export class AppComponent { 
    food = 'kielbasa';
}

Go head and refresh your browser to see the changes. Also, ensure the request is not pulling from the browser cache.

Template Syntax Example

The first thing to point out is that the template is defined using the ES2015 template literal string syntax. This syntax uses the back-tick character (grave accent) and supports multi-line string values. TypeScript outputs ES5-compatible strings at compile-time.

Also, you see two examples of Angular-specific template syntax. First, the value attribute of the input is surrounded by square brackets []. This is called a property binding because it binds to the property of an element. In this case, the input's value property is set to the resulting evaluation of the component's food property. This syntax replaces the need for a specialized Angular directive. You are instead targeting the element's native properties, setting the bindings using an abbreviated syntax.

On the second line of the template, you see the double curly braces used {{ }} to bind to the same component property. This is the interpolation syntax. When changes to the component are made, the expression inside the curly braces is evaluated and the resulting value is coerced to a string and inserted into the DOM. This syntax is similar to Angular 1.x, although some of the rules around how expressions are evaluated have changed.

Now, edit the value in the text input. You see that it doesn't update the value in the paragraph. The binding only operates from the component to the view, not the other way around.

value doesn't change

To update the value, you wire-up one of the element's events with a method on your component. Instead of wrapping the event name in square brackets [], you wrap it in parentheses () For this example use the input event and create a method on the component class called foodInput to handle the event. This is called an event binding. Your component code should now look like this:

import { Component } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'my-app',    
    template: `
        <input type="text" [value]="food" (input)="foodInput($event)"/>
        <p>Sriracha sauce is great with {{ food }}</p>
    `,
})
export class AppComponent { 
    food = 'kielbasa';

    foodInput(event: Event) {
        const target = event.target as HTMLInputElement;
        this.food = target.value;
    }
}

Notice in the template, the $event argument is passed to the foodInput method. This represents the argument that you would receive if you had handled the event in the DOM. Furthermore, look at the typings applied to the method. Both the Event and HTMLInputElement types help you use the API in the method. Ultimately, you take the new value from the event arguments and set it to the food property on the component which in turn updates the binding in the template.

value does change

In the past, you may have used two-way binding in Angular 1.x. Two-way binding is still around but the Angular framework is designed to support uni-directional (one-way) data patterns more easily out of the box. Read more about the template syntax here.

In Summary

You have now built an Angular 2 application sitting on top of ASP.NET Core from scratch. In this post, you learned how to bootstrap your application and learned about some of the fundamental building blocks of Angular 2 including components and NgModules. You also learned how to customize the settings in Visual Studio Code to hide files generated by TypeScript.

In the next post, you smooth out some of the rough edges with the development experience. Wouldn't it be great if your browser automatically updated after every code change? That's what part 5 covers so stay tuned.

How is your Angular 2 development going? If you used Angular 1.x, do you find that the frameworks are concept compatible? In what ways? Let everyone know in the comments.

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 3

Angular2, ASP.NET Core, Visual Studio Code, Part 3

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is part three in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

In this post, you configure the Angular 2 dependencies. There is a lot of material to cover. Much of this configuration has been taken directly from the Angular 2 Quick Start as it has been proven to work. There are some exceptions, though, in order to accommodate the usage of ASP.NET Core as the server-side framework instead of NodeJS.

If you would like to jump straight to the code, it's all on GitHub.

NPM Dependencies

Angular 2 and its dependencies are delivered through npm. Create a package.json file in your application directory with the following configuration:

{
  "name": "angular2-aspnetcore-starter",
  "version": "0.0.1",
  "description": "Starter application using Angular 2 and ASP.NET Core",
  "scripts": {

  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "@angular/common": "~2.2.0",
    "@angular/compiler": "~2.2.0",
    "@angular/core": "~2.2.0",
    "@angular/forms": "~2.2.0",
    "@angular/http": "~2.2.0",
    "@angular/platform-browser": "~2.2.0",
    "@angular/platform-browser-dynamic": "~2.2.0",
    "@angular/router": "~3.2.0",

    "angular-in-memory-web-api": "~0.1.15",
    "systemjs": "0.19.40",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.8",
    "rxjs": "5.0.0-beta.12",
    "zone.js": "^0.6.26"
  },
  "devDependencies": {
    "concurrently": "^3.1.0",
    "typescript": "^2.0.10",
    "@types/node": "^6.0.46"
  },
  "repository": { }
}

Update: The original version of this post omitted the @types/node package from devDependencies. This typings library should be added to your project as it contains definitions for the module.id API used in the next part of this series.

This file contains metadata for your application but most importantly it lists all of the dependencies and devDependencies. The dependencies are the libraries that your application uses at runtime. The devDependencies are libraries you use during your build.

In this project, you use TypeScript which requires a compilation/build step to convert the TypeScript code to JavaScript that the browser understands. In your devDependencies, you see typescript and concurrently listed. The concurrently library is discussed later.

As for the libraries listed under dependencies, most of these are Angular libraries. Notice how there are 9 libraries with some form of 'angular' in their name. The Angular team was deliberate in breaking down the framework so that you can reference only those pieces you need. For this example, all of them are included but you won't use them all. They are listed for reference.

There are five other runtime dependencies:

SystemJS

SystemJS is a configurable module loader. Read more about it in the dedicated section below.

core-js

This is a shim providing polyfill implementations for common ECMAScript 2015 (and beyond) features. If you aren't familiar with the concept of a shim, it's a piece of code that implements language features not natively supported by the browser. There is a list of provided features here.

reflect-metadata

This is another shim, providing support for ECMAScript decorators. Decorators are similar to annotations in C# and allow you to add metadata to JavaScript objects. Angular 2 heavily uses decorators in the framework. This is an example of the Component decorator:

@Component({
    selector: 'my-component',
})
export class MyComponent{ }

For reference, check out the reflect-metadata documentation on GitHub.

rxjs

Another shim for observables. In certain parts of Angular, especially @angular/http observables are a first-class citizen. You won't be using them in this getting started series but you should start learning about them. This 7-minute video is an excellent place to start.

zone.js

There is no use trying to explain it briefly. You don't need to understand it for now but if you're curious, go head and watch this video.

Now that your package.json file is in place, install the packages using Visual Studio Code's terminal (Ctrl+`) and type the command npm install.

TypeScript Configuration

TypeScript is arguably the best-supported language in Angular 2. It seems to be a hit in the Angular community. Also if you're used to C#, you will feel at home with having types in your JavaScript. (Although, there are significant differences between the C# and TypeScript type systems as you will come to find).

To configure the TypeScript compilation, you add a tsconfig.json file to the root of your application. This is the recommended configuration:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [ "es2015", "dom" ],
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  }
}

Along with types, TypeScript gives you the capability to use ECMAScript features that have not yet been added to the browsers. In order to target the broadest range of browser compatibility today, the target property with the value es5 tells the TypeScript compiler to emit ECMAScript 5 compatible JavaScript.

The project configuration uses node module resolution. Both the module and moduleResolution properties handle this. You can read more about TypeScript module resolution on this site or visit the TypeScript documentation.

The emitDecoratorMetadata and experimentalDecorators properties enable compilation of the ECMAScript decorator syntax that Angular 2 utilizes. And finally the lib property configuration provides types for standard ECMAScript 2015 language features and DOM (Document Object Model) APIs.

SystemJS Configuration

The SystemJS library has two responsibilities. The first is to act as a module loader. At the time of writing, today's browsers don't yet support ECMAScript 2015 modules. SystemJS acts as a shim for dynamic module loading.

Its other responsibility is to map node-based import statements to relative URLs – essentially mimicking npm-based module resolution in the browser. There is a post on this site that goes into more detail about the module-loading capabilities of SystemJS. You can also visit the documentation here.

Node module resolution allows you to import modules by package name:

import { Component } from '@angular/core';

However, the browser doesn't understand this. Therefore, for each npm-based library you use in the browser, you should have corresponding configuration telling SystemJS from where to load the scripts.

In your application, create a file named systemjs.config.js. The configuration looks like this (again, courtesy of the Angular Quick Start):

/**
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': 'node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      app: 'app',

      // angular bundles
      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
      '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
      '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',

      // other libraries
      'rxjs':                      'npm:rxjs',
      'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        main: './main.js',
        defaultExtension: 'js'
      },
      rxjs: {
        defaultExtension: 'js'
      }
    }
  });
})(this);

In particular, look in the configuration at the package called app that points to a main file, ./main.js. This is used in the next section.

Update index.html

Now that you have the tooling downloaded and configured, it's time to reference the shims, loaders, and libraries in your index.html file:

<!DOCTYPE html>
<html>
  <head>
    <title>Angular 2, ASP.NET Core Starter</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>

    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>

    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
  </head>

  <body>
  </body>
</html>

Remember the ./main.js path in the SystemJS configuration? Now look a the System.import('app')... statement in the HTML:

System.import('app').catch(function(err){ console.error(err); });

This statement uses SystemJS to import the app module, defined in the SystemJS configuration, to request app/main.js from the server. This file does not exist yet.

Start Me Up

Instead of creating app/main.js, create the app directory at the root of your application and then create a main.ts TypeScript file within the app folder.

Application Structure

Use this as the contents of the main.ts file:

document.body.innerHTML = 'Hello, TypeScript World!';

Now it's time to run the application. However, instead of typing a bunch of commands in the terminal, create an npm script.

Remember all the way back at the beginning, you installed the concurrently library from npm? This library allows you to run several commands in the terminal, umm… concurrently. Add this script to your package.json file:

"scripts" : {
    "start": "tsc && concurrently \"tsc -w\" \"dotnet run\" "
},

Now in the terminal, type npm start to compile the TypeScript and start the ASP.NET Core application. Furthermore, tsc -w runs the TypeScript compiler in watch mode so whenever you save a modified TypeScript file, the compiler regenerates the JavaScript.

Now open your browser to http://localhost:5000 and see the Hello, TypeScript World! message. In a future post, you further automate this configuration by incorporating Visual Studio Code key bindings and Browser Link.

Hello, TypeScript World!

Conclusion

Configuring the Angular 2 dependencies isn't trivial. However, understanding how these systems work will save you countless hours diagnosing issues. The modularity of npm is powerful but also comes with complexity. Now, you have a better understanding of what is happening behind the scenes of your Angular 2 application and are better equipped for your future development.

In the next post, you build on this foundation and actually write some Angular code. In the comments below, please discuss your adventures in npm configuration. There are so many options out there so if you have any tips, please leave a comment.

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 2

Angular2, ASP.NET Core, Visual Studio Code, Part 2

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is part two in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

In this post, you setup a basic ASP.NET Core application to serve static files using the terminal in Visual Studio Code. To ensure you have the proper dependencies installed, please see the first post.

.NET Core SDK Preview 3: This tutorial uses .NET Core SDK Preview 3 which is available on GitHub. This version includes 'alpha' support for MSBuild-based projects that use .csproj configuration instead of project.json configuration. Microsoft announced that MSBuild is the common project configuration for .NET Core based projects going forward. By using MSBuild, the goal is to better prepare you for future versions of the tooling.

If you would like to jump straight to the code, it's all on GitHub.

The .NET Core CLI

The .NET Core command-line interface (CLI) is the base, cross-platform level of tooling provided with the .NET Core framework. The recommendation is that all other tooling is built off of this base making it an attractive place to start learning the framework.

First create a directory in which you will build this application using whichever tool you prefer (command/terminal window, file explorer). Then open Visual Studio Code. Now from the File menu, select Open Folder… to open the target directory.

open folder

Note: there are several ways to open a specific directory in Visual Studio Code. First if already in a command/terminal window, use the command code . to open up the current directory in Visual Studio Code. Also if in Windows File Explorer, right-click on a directory to open in Visual Studio Code.

You now have your application directory setup in Visual Studio Code. Press Ctrl + ` to open Visual Studio Code's terminal.

Next, type the command dotnet new in the terminal pane. This command creates two files in your application directory: a .csproj named after the current folder and Program.cs. The .csproj contains the information needed by the build to create your application. The Program.cs file contains the code that executes when the application runs.

Note: you may have seen a .xproj file extension paired with a project.json file in previous versions of ASP.NET Core. Going forward, the standard is to use .csproj or the equivalent file extension for your chosen language.

Before running the application, you must download the required dependencies. In the terminal, type dotnet restore. This command downloads packages from Nuget required to build and run your .NET-based application.

Once the dotnet restore command is complete, type dotnet run to build and run the code. You should see "Hello World!" displayed in the terminal. Congratulations, you built your first .NET Core application!

Now the objective is to move "Hello World!" from the terminal to the browser.

Initialize the Web Host and Kestrel

In ASP.NET Core, the web host bootstraps and manages a server. The server handles the HTTP requests and responses. So you need a host in order to have a server.

First, modify your .csproj file with the required dependencies. It should look like this:

<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp1.0</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
        <Compile Include="**\*.cs" />
        <EmbeddedResource Include="**\*.resx" />
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.NETCore.App">
        <Version>1.1.0</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.NET.Sdk.Web">
        <Version>1.0.0-alpha-20161104-2-112</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.AspNetCore.Hosting">
        <Version>1.1.0</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel">
        <Version>1.1.0</Version>
        </PackageReference>
    </ItemGroup>

    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Then run dotnet restore from the terminal to download the newly added packages.

The web host and web server are configured together using a series of extension methods. For this example, you are using Kestrel, a light-weight and cross-platform server designed for ASP.NET Core. The application's entry point is the static void Main method found in Program.cs. Replace the code in Program.cs with the following to configure the web host and web server:

using System.IO;
using Microsoft.AspNetCore.Hosting;

class Program
{
    static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseWebRoot(Directory.GetCurrentDirectory())
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

The new WebHostBuilder() constructor returns an IWebHostBuilder instance which is then configured using extension methods. The UseKestrel() extension method configures the host to use the Kestrel web server.

Create one more file in your application directory named Startup.cs, with a class named Startup. When creating a web host, you must provide a class containing startup configuration information. The startup class must contain a public void Configure() method to complete the configuration contract. You will come back to this file, later. For now, the code should look like this:

public class Startup
{
    public void Configure() { }
}

The UseContentRoot() method configures ASP.NET Core to use the specified directory when looking for static files during ASP.NET operations. The method Directory.GetCurrentDirectory() gets the path of the current working directory which for this example is the directory in which Program.cs resides.

Note: with this version of the SDK, you may see some of your code decorated with green underlines saying something about mimatched versions of System.Runtime. The SDK tooling is still in preview and this should not prevent you from completing the steps.

The UseWebRoot() method deserves some explanation. the web root is different than the previously configured content root. Think of content root as being a base path for the ASP.NET framework versus web root being the base path for the web server. Most of the templates for ASP.NET Core use the default web root which is a directory named wwwroot. However, a lot of the getting started Angular and front-end examples out there use the working directory as the web root not to mention that this behavior mirrors the original ASP.NET behavior. Use the working directory as a simple configuration while getting started.

Note: At some point when you begin to pre-compile and bundle your Angular application, having a separate web root such as wwwroot makes sense to separate your source code from your deployable assets so it's important to note this configuration option.

Finally, the Build() method packages this extension-method-based configuration into an IWebHost instance which is then started by calling its Run() method. Now in the terminal (Ctrl + `), type dotnet run and your application compiles and runs on http://localhost:5000 by default. At this point, just confirm the project starts in the terminal. There is nothing more to see yet. Shut down the application by placing focus in the terminal and typing Ctrl+C.

Note: As with the original Visual Studio, the F12 key takes you to the defintion of an API.

Configure Static File Support

In order to actually serve an HTML file to the client, you must enable static file support in ASP.NET Core. You need to download a new Nuget package and configure with the Startup class.

First, go to your .csproj file and add the following reference:

<PackageReference Include="Microsoft.AspNetCore.StaticFiles">
  <Version>1.1.0</Version>
</PackageReference>

Once you have added the reference, restore the package with dotnet restore in the terminal.

Once restored, go to the Startup.cs file. Similar to configuring the web host, you configure the ASP.NET application using extension methods. The new configuration looks like this:

using Microsoft.AspNetCore.Builder;    

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseDefaultFiles();
        app.UseStaticFiles();
    }
}

Save your files and continue to the next section.

Hello, World!

Now, add an index.html file to your application directory with the contents Hello, World!. In the terminal, type dotnet run and then visit http://localhost:5000 in your browser. You should see Hello, World! displayed. Congratulations, you built a basic ASP.NET Core application from scratch!

Hello, World!

Conclusion

If you are an experienced ASP.NET developer in Visual Studio, you might be thinking how much you took for granted with the framework and tooling in the past. This setup is significantly different than File, New Project in Visual Studio so please refer to the code on GitHub.

Now you understand the basic mechanics of starting an ASP.NET Core application. You setup a web host, web server, and static file support. You know the difference between content root and web root. With this scaffolding, it's time to start building the Angular 2 piece in the next post.

Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 1

Angular2, ASP.NET Core, Visual Studio Code, Part 1

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is the first in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

Why so many posts? The idea is to take you from nothing and not only build the application but to detail why it's built in this manner. There are numerous options when it comes to web development and for many readers this tutorial will walk you through two new frameworks and a new code editor so breaking up the content allows for sufficient explanation.

In this particular post, you install the tools used throughout the remaining posts. The post also provides a tour of the main Visual Studio Code features used to create the application.

Prepare Your Machine

These are the frameworks and tools to install before writing any code:

Mac and Linux Users: Thought was taken to omit Windows-specific features and tooling from this post series but ultimately the example was written on a Windows machine without verifying on MacOS or Linux. Please leave any feedback for MacOS or Linux development in the comments. Thank you.

.NET Core SDK Preview 3: This tutorial uses .NET Core SDK Preview 3 which is available on GitHub. This version includes 'alpha' support for MSBuild-based projects that use .csproj configuration instead of project.json configuration. Microsoft announced that MSBuild is the common project configuration for .NET Core based projects going forward. By using MSBuild, the goal is to better prepare you for future versions of the tooling.

Node.js and npm

No you aren't writing a Node.js application. However, the framework has become the defacto tooling standard for pre-processing your HTML, JavaScript, and CSS before it hits the browser. For instance, the Angular 2 application is built in TypeScript which requires compilation into JavaScript. Node.js fills this role in the application.

As important as Node.js is its package manager, npm. This tool has also become the defacto standard for obtaining web development libraries and tooling. Node.js and npm are included in the same installer available in both a current and LTS (long-term support) version. The LTS version is recommended for most users. Make sure to have node version 4.x.x or higher and npm version 3.x.x or higher. You will check them later while touring Visual Studio Code.

.NET Core

To be clear, this is not the .NET Framework of old. The .NET Core framework is built from the ground up to be cross-platform and fast. This download includes the .NET Core and ASP.NET Core Frameworks as well as the terminal/command line tools used to create the backend in this tutorial.

While higher-order features such as Routing, Views, Controllers are similar to their ASP.NET 4.6 counterparts, setting up and configuring an ASP.NET Core application is noticeably different and you will even start it from the terminal/command line.

For this tutorial, use the .NET Core Preview 3 SDK. Later in this post, you will check which version is installed. It should be 1.0.0-preview3-x or higher.

Visual Studio Code

Visual Studio Code is one of the newer additions to the Visual Studio family. Forget anything you knew about traditional Visual Studio, this is a different animal entirely. During installation, you can add Visual Studio Code to your PATH variable. This enables the ability to type code . in the terminal/command window and open the current directory in Visual Studio Code.

Get to Know Visual Studio Code

This application is built entirely in Visual Studio Code. While this is not an exhaustive tour, it points out the main features of the editor relevant to building the application and continues setting up the editor for your project.

Explorer Pane

Put simply, this is where your files are listed. You point Visual Studio Code to a directory and this pane lists all the files and folders in that directory, including those that are currently open in the editor. You can create new files or folders directly in the explorer pane and to edit a file, simply click on it and it opens in the editor.

Image

Integrated Terminal

The integreated terminal in Visual Studio Code is exactly that. Instead of switching between your editor and a seperate instance of your terminal/command window, you run commands directly in the editor. This walkthrough exclusively uses the integrated terminal, but of course using a separate terminal/command window works fine as well.

Image

Go head and try it out:

  1. Press Ctrl + ` to open the Integrated Terminal
  2. Type node -v then Enter to get the Node.js version. It should be 4.x.x or higher.
  3. Type npm -v then Enter to get the npm version. It should be 3.x.x or higher.
  4. Type dotnet --version then Enter to get the .NET Core SDK verion. It should be 1.0.0-preview3-x or higher.
  5. Press Ctrl + ` to close the Integrated Terminal

If at any point these commands fail, it most likely means that either the framework is not installed or isn't added to your PATH. On windows at least, try restarting to refresh your PATH variable.

Command Palette

If you only remember one keyboard shortcut in Visual Studio Code, it should be Ctrl + Shift + P to open the command palette. The command palette contains almost every operation you want to complete in Visual Studio Code. Just start typing and it filters the list of operations for you. You're fingers never have to leave the keyboard.

Image

You still need to install the C# extension (from Microsoft) in Visual Studio Code before you start coding. Try to install it using the command palette. If you get stuck, you can also find it here.

These are the key features in Visual Studio Code used during the walkthrough. There are so many other great features, so please read more about them in the Visual Studio Code documentation.

Wrapping up

In this first post, you have installed the necessary frameworks and tools for your project. You have also started familiarizing yourslef with Visual Studio Code. In the next post, you leverage these frameworks, tools, and skills to build a simple ASP.NET Core backend from scratch.

Did you start exploring Visual Studio Code? Please leave a comment below regarding your tips, tricks, or favorite features in the editor.