The following tutorial uses .NET Core 1.0.3 SDK Preview 2 build 3156 which can be downloaded from https://github.com/dotnet/core/blob/master/release-notes/download-archives/1.0.3-preview2-download.md. Future version of .NET Core may not work with this tutorial.

Changing the Programming World with
Angular 2 and .NET Core on a Mac in 10 Steps

Angular 2 and .NET Core are new technologies taking the programming world by storm. Angular 2 is a next generation cutting-edge cross-platform user interface framework for web applications. .NET Core is a backend framework from Microsoft that is now available on Windows, Mac and Linux. While these two technologies exist and are used independently of each other, they can be combined to build applications for any client/server platform.

This tutorial will be the first in a series that will teach you how to build a complete application with Angular 2 and .NET Core with Visual Studio Code on a Mac.

The goal of this first tutorial is to build a small project to fire up a .NET Core web server and display a Hello World Angular 2 component. We will build the entire project from scratch using the tools provided by .NET Core and Node.js. If you wish to skip this and download the project in its final initial configuration, visit the following GitHub project to download or clone the project. Be sure to read through the tutorial to learn more about the parts of the project and their role in the overall solution.

https://github.com/training4developers/dotnet-core-angular2-starter

While this tutorial is geared towards a Mac environment, it should work similarly on a Windows or Linux system. For Windows, use a Windows Command prompt instead of a terminal, and where folder paths are used, modify them for the Windows environment. For Linux, almost everything should be the same, except that the Linux install of .NET Core, Node.js and Visual Studio Code may be slightly different.

Step 1 – Install Visual Studio Code

While any editor supporting JavaScript, TypeScript, and C# syntax can be used, the preferred editor for working on .NET Core applications (and even Angular 2 in my opinion) is Visual Studio Code. Visual Studio Code is an Electron Framework-based application, and it is completely cross-platform, running on Windows, Mac and Linux. It provides a rich extension library allowing the editor to be configured for almost any kind of programming environment.

To install Visual Studio Code, visit http://code.visualstudio.com, download and execute the installer, and then follow the instructions to install it.

There are two main versions of Visual Studio Code, the regular version and an Insiders version. Essentially, the Insiders version is a daily build which includes the latest features and bug fixes. Typically, I prefer using this version. Occasionally the Insiders stream will release a buggy version that does not work properly. When this occurs, I fall back to the official release. If you like to work with tooling near the bleeding edge (but not on the bleeding edge) then I recommend the Insiders version for you. It can be downloaded from https://code.visualstudio.com/insiders.

Once installed, the C# extension for Visual Studio Code needs to be installed. To install it click the Extension toolbar link on the left-hand side of Visual Studio Code. The Extension box will open with a search box at the top. In the search box type C#. Click Install on the C# extension published by Microsoft.

Step 2 – Install Node.js and .NET Core

Angular 2 is distributed as Node.js Packages via NPM (Node Package Manager). To work with Angular 2, Node.js 6 or later is required. Node.js is simple to install. Download Node.js from http://www.nodejs.org/. Run the installer, accepting the default options.

Once Node.js is installed, .NET Core needs to be installed. .NET Core is easily downloaded, but the configuration before the installation is a little more involved. .NET Core requires the latest version of OpenSSL, which is not pre-installed on a Mac. The easiest way to install the latest version of OpenSSL is through another very common Mac Package Manager named Homebrew. For complete details, visit the .NET Core web site and complete the instructions to install .NET Core, https://www.microsoft.com/net/core.

As part of the install, the .NET Core setup instructions will have you create a .NET Core Hello World application. Create that application to verify that .NET Core was successfully completed, and then restore the NuGet packages over your network connection.

Step 3 – Install Yeoman and the ASP.NET Generator

In Visual Studio 2015 (and other big IDE development tooling), when creating a new project, a template can be chosen and after answering a few questions the initial files are created for the project. Visual Studio Code does not provide project creation tools, instead it relies upon the framework technology to create the project (Node.js and NPM is a good example of this), and then Visual Studio Code is used to code the project. For ASP.NET projects within .NET Core, the Yeoman Generator is used to create new projects. Yeoman is a Node.js based generator program used to create all kinds of projects for different technology platforms.

Throughout the tutorial, the $ will be used to indicate a command being run from a terminal prompt. For Mac, these commands can run directly from the Terminal application, or from the terminal inside Visual Studio Code. For Windows, these terminal commands should be run from a Windows Command Prompt window or the terminal inside Visual Studio Code. Please adjust the path formatting to work with Windows. For Linux users, you already know what a terminal is, so enough said.

To use Yeoman, the generator itself and the ASP.NET generator configuration must be installed. To install Yeoman and the ASP.NET Generator, perform the following steps:

  1. Open a Terminal window, and change to your folder when you create new projects. If you do not have such a folder, then create a new folder named projects under your user's root folder. Then change to that folder.

      $ mkdir ~/dotnet_projects
      $ cd ~/dotnet_projects
  2. Run the following command to install Yeoman, Bower, and ASP.NET Generator:

      $ npm install -g yo bower generator-aspnet

This may require super user permissions. If it does, then use sudo. Ideally, your Mac can be configured to not require super user permissions. For more information, visit this web page: https://docs.npmjs.com/getting-started/fixing-npm-permissions. Linux may require super user permissions as well. Windows should not require administrative privileges as NPM packages are stored globally within a specific user's account only, not global for the whole system as they are for Mac and Linux.

  1. Run Yeoman to create a new ASP.NET project.

        $ yo aspnet
  2. A series of questions will be asked to configure the new project. Select the Empty Web Application project type. After selecting the project type, enter the following name for the project: WidgetsApp. With the project named, the project files will be created and instructions will be provided to restore the NuGet packages for the project.

        $ cd WidgetsApp
        $ dotnet restore

The dotnet restore command will install the NuGet packages registered in the package.json file as part of the initial project creation. Later in the tutorial, additional NuGet packages will be added to the project.json file and dotnet restore will be executed to install those additional packages.

Step 4 – Open the project with Visual Studio Code

From the terminal window, open the project with Visual Studio Code.

$ open -a "Visual Studio Code" .

The period following the string “Visual Studio Code” is important and indicates the editor should open the current folder as the project folder. The project will open in Visual Studio Code with the project folder and its contents listed in the side bar to the left.

If you choose to use Visual Studio Code Insiders edition, the above command will be slightly different.

  $ open -a "Visual Studio Code - Insiders" .

The dash in the program name is part of its name, and needs to be included.

When the project is initially opened with Visual Studio Code you may be prompted with a warning message from Visual Studio Code asking you if you would like to install assets required to build and debug the project. Click "Yes".

Step 5 – Install Additional NuGet Packages

To build out the ASP.NET portion of the web application, additional NuGet packages will be needed. Unlike the more feature-rich package manager for Node, NPM, the dotnet CLI program does not support adding (installing) new packages in .NET Core projects. To add new packages, entries must be added directly to the project.json file. The project.json file mimics the package.json file used by Node.js programs for managing NPM packages.

Side Note: Microsoft plans to replace the project.json file in a future .NET Core release with standard MSBuild files. To read more about this visit: https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json. For the time being, project configuration should still be accomplished the project.json file.

Since the dotnet CLI program does not provide an easy way to install NuGet packages, simply copy the project.json file below and replace the contents of the original project.json file provided as part of the Yeoman process.

{
  "dependencies": {

    "Microsoft.NETCore.App": {
        "version": "1.1.0",
        "type": "platform"
    },
      // added to support MVC 
      "Microsoft.AspNetCore.Mvc": "1.1.0",
      "Microsoft.AspNetCore.Routing": "1.1.0",
      "Microsoft.AspNetCore.StaticFiles": "1.1.0",

      "Microsoft.AspNetCore.Diagnostics": "1.1.0",
      "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
      "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",

      "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
      "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
      "Microsoft.Extensions.Configuration.Json": "1.1.0",
      "Microsoft.Extensions.Configuration.CommandLine": "1.1.0",
      
      // added to support Logging
      "Microsoft.Extensions.Logging": "1.1.0",
      "Microsoft.Extensions.Logging.Console": "1.1.0",
      "Microsoft.Extensions.Logging.Debug": "1.1.0",
      
      // added to support Entity Framework
      "Microsoft.EntityFrameworkCore.SQLite": "1.1.0",
      "Microsoft.EntityFrameworkCore.Design": "1.1.0"
    },

    "tools": {
      "Microsoft.AspNetCore.Razor.Tools": "1.1.0-preview4-final",
      "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final",
      "Microsoft.EntityFrameworkCore.Tools.DotNet": "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"
        ]
      }
    },

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

    "buildOptions": {
      "emitEntryPoint": true,
      "preserveCompilationContext": true,
      "compile": {
        "exclude": [ "node_modules" ]
      }
    },

    "runtimeOptions": {
      "configProperties": {
        "System.GC.Server": true
      }
    },

    "publishOptions": {
      "include": [
        "wwwroot",
        "**/*.cshtml",
        "appsettings.json",
        "web.config"
      ]
    },

    "scripts": {
      "postpublish": [ 
        "dotnet publish-iis --publish-folder %publish:OutputPath% 
        --framework %publish:FullTargetFramework%" ]
    },

    "tooling": {
      "defaultNamespace": "Training4Developers"
    }
  }

Save the file, open a terminal (change to the project folder), and run the following command.

$ dotnet restore

The new packages added to the project.json file should now be downloaded and installed into the project.

When saving the project.json file, Visual Studio Code may offer to restore the new NuGet package references. If you allow Visual Studio Code to do this, then running dotnet restore from the terminal is not needed.

Step 6 – Install Angular 2 Node.js Packages

With the .NET Core packages installed, the client-side Angular 2 packages need to be installed via Node.js. While an in-depth discussion of Node.js beyond the scope of this tutorial, it would be beneficial to know a few basics of Node.js and its package manager NPM.

Node.js and NPM are two separate projects, distributed together. The Node.js version and NPM version are never the same. Node.js is the framework (like .NET and Java) and NPM is the package manager (like NuGet and Maven). NPM performs many operations such as initializing projects, installing packages, and uninstalling packages.

To manage a project's dependencies, NPM uses a package.json file. This file contains metadata about the project, package dependencies, and script command to perform various project related tasks (such as running the project or executing tests). NPM is not used to manage .NET Core NuGet packages. NPM is used to manage development tooling, such as Webpack and SASS transpilation, and client-side packages, such as Angular 2.0.

.NET Core + Angular 2 projects are a blending of two different framework and package manager tools to produce a single project. As mentioned at the outset, each can and is frequently used independently of each other, but when combined they provide a powerful environment for building next generation web applications.

Create a new file name package.json in the main project folder, and copy the configuration below. While NPM has excellent package installation capabilities, for the sake of time and configuration sanity, copying the configuration below is easier way to get up and running versus installing each package manually.

{
  "name": "dotnet-core-angular2-starter",
"version": "1.0.0",
"scripts": {
"start": "npm run webpack-once && dotnet run",
"postinstall": "npm run typings && dotnet restore",
"typings": "typings install",
"clean": "rimraf wwwroot",
"webpack": "webpack --config ./webpack.config.js --watch",
"webpack-once": "webpack --config ./webpack.config.js"
},
"engines": {
"node": "6.7.0"
},
"keywords": [],
"author": "Eric W. Greene",
"license": "MIT",
"devDependencies": {
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "2.0.0-beta.4",
"file-loader": "^0.9.0",
"html-loader": "^0.4.3",
"lodash": "^4.17.2",
"node-sass": "^3.13.0",
"null-loader": "^0.1.1",
"raw-loader": "^0.5.1",
"resolve-url-loader": "^1.4.4",
"rimraf": "^2.5.2",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1",
"ts-helpers": "^1.1.1",
"ts-loader": "^1.2.2",
"typescript": "^2.1.1",
"typings": "^2.0.0",
"url-loader": "^0.5.7",
"webpack": "^1.13.3"
},
"dependencies": {
"@angular/common": "^2.2.4",
"@angular/compiler": "^2.2.4",
"@angular/core": "^2.2.4",
"@angular/forms": "^2.2.4",
"@angular/http": "^2.2.4",
"@angular/platform-browser": "^2.2.4",
"@angular/platform-browser-dynamic": "^2.2.4",
"@angular/router": "^3.2.4",
"angular2-in-memory-web-api": "0.0.21",
"bootstrap": "4.0.0-alpha.5",
"bootstrap-loader": "2.0.0-beta.12",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.8",
"rxjs": "^5.0.0-rc.4",
"symbol-observable": "^1.0.3",
"systemjs": "^0.19.41",
"zone.js": "^0.7.2"
}
}

In addition to installing the NPM packages, some additional TypeScript typings files need to be installed as well. These typings will be used by the TypeScript compiler and the Visual Studio Code editor to provide strong typing support for the Core.JS, Jasmine, and Node libraries.

Create a new typings.json file in the main project folder and copy the following configuration.

{
    "globalDependencies": {
"core-js": "registry:dt/core-js",
"jasmine": "registry:dt/jasmine",
"node": "registry:dt/node"
}
}

Open a terminal window within Visual Studio Code with CTRL+` (control key plus backtick).

From the terminal, run the following command to install the NPM packages and TypeScript typings:

$ npm i

The process will install all the NPM packages needed to run Angular 2 including tools such as Webpack, SASS, and Bootstrap. Once the packages are installed, the postinstall script will install the required TypeScript typings for Core.js, Jasmine, and Node.js. The postInstall will also restore missing NuGet packages. While that step is not needed because of earlier steps in this tutorial, when this project is cloned (or downloaded) from Git in the future, this NPM post install command will allow both NPM packages and NuGet packages to be installed with a single convenient command: npm i.

Note: The installation process may take a few minutes. If the install seems to hang give it 3-5 minutes before terminating with Control-c and trying again. You can always delete the node_modules folder and start again with a fresh module installation at any point in the application's development process. When running any Node.js project, if any odd, unexplained, confusing errors not related to the specific code of the project occur, it is usually the result of a corrupted node_modules installation. Simply delete the node_modules folder, and install again with npm i.

Step 7 – Setup Configuration Files

Several files are needed to configure the server-side and client-side portions of the application. The tsconfig.json file will configure the TypeScript compiler and the editor's TypeScript support. The appsettings.json file will provide runtime configuration details for the ASP.NET application. The webpack.config.js file will configure the Webpack bundler to support TypeScript and SASS files, detail how to bundle the files, and configure additional options such as source maps.

The popular CSS framework, Bootstrap (version 4), is included in the project build as well. The JavaScript portion of Bootstrap is not being loaded, but the CSS framework is and will be used to build the application. To configure how Webpack loaded Bootstrap into the bundle, the .bootstraprc file is provided.

Following the steps below, quickly create the following configuration files by copy and pasting the configuration .

Create a new file named tsconfig.json in the main project folder, and copy the following configuration:

{
"compileOnSave": false,
"buildOnSave": false,
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noImplicitAny": true,
"removeComments": false,
"noEmitHelpers": false,
"sourceMap": true,
"inlineSourceMap": false,
"suppressImplicitAnyIndexErrors": true
},
"filesGlob": [
"./src/js/**/*.ts",
"./typings/index.d.ts",
"!./node_modules/**"
] }

The tsconfig.json file specifies the configuration for the TypeScript compiler responsible for transpiling the TypeScript code to ES5-compliant JavaScript code that runs in web browsers. The compileOnSave and buildOnSave configuration options are set to the false so Visual Studio Code does not attempt to compile the TypeScript files for us on save. Instead, Webpack running in watch mode will detect our file changes and compile our files when we save them.

The target option specifies that we are targeting ES5 browsers. The default value is ES3, but most likely you are targeting browsers more modern than this. If you are only supporting the most recent browsers, this can be set to ES6. The module and moduleResolution options configure TypeScript to output ES2015 modules as CommonJS, and to search for modules using the Node.js module resolution algorithm. Ultimately, Webpack will bundle the JavaScript code using the CommonJS modules.

The emitDecoratorMetadata and experimentalDecorators options are set to true to enable the use of decorators in TypeScript. Unlike most of the features of TypeScript (other than strong-typing), decorators are not yet officially part of any JavaScript specification. Nevertheless, Angular 2 uses decorators to configure the role of classes and properties in the Angular 2 system (such as identifying classes as Components, Directives, Pipes, etc.) For various reasons, Angular 2 chose this approach over using inheritance (React uses inheritance to identify classes as Components). To support this approach, experimental support for decorators must be enabled in TypeScript.

The option noImplicitAny requires each variable to be defined with a type including the type any. Leaving off a type declaration will not result in an implicit any type being assigned, and an error will be thrown. To enable source maps, the sourceMaps option is set to true. Finally, the fileGlobs option identify files which should be included and excluded in the TypeScript compilation process.

Create a new file named appsettings.json in the main project folder, and copy the following configuration.

{
"ConnectionStrings": {
"DefaultConnection": "Filename=./widgets.db"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

The ConnectionStrings configuration is where database connection strings are stored. The DefaultConnection for this project will point to a local SQLite database file. If desired, the project could be configured to connect to any number of databases that provide .NET Core drivers such as SQL Server, SQL Azure or MySQL.

The Logging configuration provides various options for the configuring how logging works for the application.

Create a new file named webpack.config.js in the main project folder and copy the following configuration:

'use strict';

const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin'); const srcFolder = 'wwwrootsrc';
const distFolder = 'wwwroot';
const jsFolderPath = `./${srcFolder}/js`; module.exports = {
entry: {
'vendor': `${jsFolderPath}/vendor.ts`,
'polyfills': `${jsFolderPath}/polyfills.ts`,
'app': `${jsFolderPath}/main.ts`
},
resolve: {
extensions: ['', '.ts', '.js', '.json'],
root: path.join(__dirname, srcFolder, 'js')
},
module: {
loaders: [ { test: /\.ts$/, loader: 'ts' }, { test: /\.json$/, loader: 'json' }, { test: /\.html$/, loader: 'html' }, { test: /\.scss$/, exclude: [ path.join(__dirname, srcFolder, 'js') ], loaders: ['style','css','sass'] }, { test: /\.scss$/, exclude: [ path.join(__dirname, srcFolder, 'css') ], loaders: ['raw','sass'] } ] },
plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: ['app', 'vendor', 'polyfills'] }), new CopyWebpackPlugin([ { from: path.join(__dirname, srcFolder, 'images'), to: path.join(__dirname, distFolder, 'images') }]) ], devtool: 'source-map', output: { path: path.join(__dirname, distFolder, 'js'), filename: '[name].js' } };

Please the read the comments in the Webpack configuration file above to understand what each part does.

Create a new file named .bootstraprc (yes there is a leading period in the file name) in the main project folder, and copy the following configuration in the file.

loglevel: disabled
bootstrapVersion: 4
useFlexbox: true
styleLoaders:
  - style
  - css
  - sass
extractStyles: false
styles: true
scripts: false
  • The Bootstrap configuration enables Bootstrap version 4 (https://v4-alpha.getbootstrap.com/).
  • The useFlexbox option enables FlexBox layout support.
  • The styleLoaders option corresponds to the loader configuration seen in Webpack. The loaders run in the order of bottom to top.
  • The extractStyles option places the CSS in an external file. By setting this to false, CSS styles will be added to the JavaScript file and loaded programmatically.
  • The styles option is set to true to include the CSS portion of Bootstrap, while setting scripts to false excludes the JavaScript portion of Bootstrap.

The JavaScript portion is being excluded because of its use of jQuery and direct DOM manipulation which is not really compatible with Angular 2's approach to the DOM.

Step 8 – Create Server-Side Files

First, the server-side code folders need to be created. From the top-level project folder, create a folder named Controllers and a folder named Views. Under the Views folder, create two folders, one named Home and one named Shared.

The resulting folder paths should look like this:

<project folder>/Controllers
<project folder>/Views
<project folder>/Views/Home
<project folder>/Views/Shared

Within each of these folders, files will need to be added.

In the Controllers folder, create a new file named Home.cs. Copy and paste the following code into the file:

using Microsoft.AspNetCore.Mvc;
namespace Training4Developers
{
    public class Home: Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

The Home controller file will handle requests to the web server, and return back the default Home view. The Home view will contain the “index.html” file of the web application, including references to the JavaScript files needed to run the Angular 2 application.

The next two files to be created are helper files for the ASP.NET MVC view system. These two files are to be placed in the Views folder.

Name the first file _ViewImports.cshtml, and copy the following code into the file:

@using Training4Developers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Name the second file, _ViewStart.cshtml, and copy the following code into the file.

@{
  Layout = "_Layout";
}

With the ASP.NET view helper files configured, now the default layout file and the specific home view need to be added.

In the Views/Shared folder, add a new file named _Layout.cshtml. Copy and paste the following code into the file:

<!DOCTYPE html>
<html lang="en"> <head> <title>Angular 2 + .NET Core Widgets Application [t4d.io]</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <base href="/">
</head>

<body>
@RenderBody() <script src="js/polyfills.js"></script> <script src="js/vendor.js"></script> <script src="js/app.js"></script> </body>

</html>

Finally, the file for the home view needs to be created. Create a new file in the Views/Home folder named Index.cshtml. Copy and paste the following code into the file:

<main class='container-fluid'></main>

ASP.NET applications have a special class named Startup. The Startup class is where services are configured. This class will be used to load configurations, setup database and ASP.NET MVC services, etc. For this first tutorial, configuration loading code and ASP.NET MVC service code would need to be added to enable the web application to properly route to the Home Controller and serve up the default Home View.

Open the file Startup.cs in the main project folder and perform the following steps to configure it for our project:

  1. Add the following namespace to the using section of the file.

    using Microsoft.Extensions.Configuration;

  2. Add the following configuration property to the Startup class.

    public IConfigurationRoot Configuration { get; set; }

  3. Using the code below, add a constructor to the Startup class.

    public Startup(IHostingEnvironment env) {
      var builder = new ConfigurationBuilder()
      .SetBasePath(env.ContentRootPath)
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
      .AddEnvironmentVariables();
                  
    Configuration = builder.Build(); }

  4. To the ConfigureServices method, add the following line of code to register the MVC services.

    services.AddMvc();

  5. Replace the loggerFactory line of code in the Configure method with the following code.

    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
      
  6. Replace the app.Run code lines in the Configure method with the following code.

    app.UseStaticFiles();
    app.UseMvc(routes => {
      routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
      routes.MapRoute("spa-fallback", "{*anything}", new { controller = "Home", action = "Index" });
    });

The server-side files are now complete. In future tutorials, additional code for new views, database access and REST services will be added. For this initial Hello World demo, serving up a single view is all that is required.

Step 9 – Create Client-Side Files

Angular 2 with Webpack requires numerous code files to display Hello World. While this is a little painful, once the environment is setup, writing new Angular 2 custom parts, such as Components or Services, is very easy.

When ASP.NET application execute, they are configured by default to serve files from the wwwroot folder. To avoid reconfiguring ASP.NET default settings, the project is going to be configured to have a wwwroot and a wwwrootsrc folder. The wwwrootsrc folder will contain the project's HTML, TypeScript, and SASS files. Web browsers cannot understand these files directly, so the Webpack bundler, combined with a number of transpilers, will process the code in the wwwrootsrc folder, and output standards-based HTML, CSS, and JavaScript code to the wwwroot folder that the ASP.NET application will serve.

First, a folder is needed to hold the client-side files. Through the Visual Studio Code folder tree, create a new folder named wwwrootsrc in the main folder (same folder as the package.json and project.json files). The wwwrootsrc and wwwroot folders should be siblings in the same parent folder.

Under the wwwrootsrc folder, create three subfolders: css, images, and js.

Under the wwwrootsrc/js folder, create an app folder.

The following folders should now exist, and contain no files.

<project folder>/wwwrootsrc/css
<project folder>/wwwrootsrc/images
<project folder>/wwwrootsrc/js
<project folder>/wwwrootsrc/js/app

With the folders created, please add the following files to their respective folders. To understand the role and purpose of each file, please read the comments included within each file.

In the wwwrootsrc/css folder, create a new file named styles.scss. Copy and paste the following code into the file:

body {
     margin:10px;
}

In the wwwrootsrc/js folder, create a new file named main.ts. Copy and paste the following code into the file:

// Used to bootstrap the application in a web browser environment
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; // The function enableProdMode switches the application to prod mode when invoked
import { enableProdMode } from '@angular/core'; // in proc mode special development and debugging
// capabilities are turned off to improve performance
if (String(process.env['ENV']).toLowerCase() === 'production') { enableProdMode(); } // import the AppModule
import { AppModule } from './app/app.module'; // bootstrap the application from the AppModule
platformBrowserDynamic().bootstrapModule(AppModule);

In the wwwrootsrc/js folder, create a new file named polyfills.ts. Copy and paste the following code into the file:

// Imports various polyfills to support older browsers, as well
// as equip modern browsers with next generation capabilities
// such as zones and web components

import 'core-js/es6';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';

if (String(process.env['ENV']).toLowerCase() !== 'production') {
  Error['stackTraceLimit'] = Infinity;
  require('zone.js/dist/long-stack-trace-zone');
}

In the wwwrootsrc/js folder, create a new file named vendor.ts. Copy and paste the following code into the file:

// Imports various third-party application libraries including Angular 2 itself

// Angular 2
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';
import '@angular/forms';

// RxJS
import 'rxjs';

// Other vendors for example jQuery, Lodash or Bootstrap
// You can import js, ts, css, sass, ... import 'bootstrap-loader';

In the wwwrootsrc/js/app folder, create new file named app.module.ts. Copy and paste the following code into the file.

// The NgModule decorator is use to decorate classes to identify
// them as module classes in the Angular 2 application
import { NgModule } from '@angular/core';

// Imports the Browser Module to run the Angular 2 application in
// a web browser environment. At the moment, Angular 2 applications
// typically run in a web browser environment, but this is expected
// to expand to native apps, such as iOS apps, in the near future
// meaning Angular 2 will not be limited to a web browser environment,
// and other platform modules will be available.
import { BrowserModule } from '@angular/platform-browser';

// Import the AppComponent so it can be registered with the AppModule
import { AppComponent } from './app.component';

// Imports the global styles for the application
// Angular 2 apps have two kinds of styles, global and component-specific
// styles. Global styles are referenced in the App Module, while
// component specific styles are referenced via the styles option on
// each component's decorator configuration   
import '../../css/styles.scss';

// Decorates the class to be an Angular 2 module
// Each Angular 2 application has a top-level AppModule
// from which the application bootstraps itself
@NgModule({
    imports: [ BrowserModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

In the wwwrootsrc/js/app folder, create new file named app.component.ts. Copy and paste the following code into the file:

// imports the Component decorator from the core
// Angular 2 module
import { Component } from '@angular/core'; // The Component Decorator configures this class
// to serve as a component in the Angular 2 application

@Component({
// Used to identify the element the component will be applied to in
// the DOM structure of the web page
selector: 'main',
// Loads the component's specific styles
styles: [require('./app.component.scss')],
// Loads the component's template
template: require('./app.component.html')
})
export class AppComponent {

// sets a property on the component which will be referenced
// as a template variable in the template file
message: string = 'Hello World!'; }

In the wwwrootsrc/js/app folder, create new file named app.component.html. Copy and paste the following code into the file:

<!-- populates the message template variable from the message property defined on AppComponent -->
<h1>{{message}}</h1>

In the wwwrootsrc/js/app folder, create new file named app.component.scss. Copy and paste the following code into the file:

// These styles will apply to the component only.
// Angular 2 by default emulates the Web Component
// concept of the Shadow DOM allowing style encapsulation. h1 { color:blue;
}

Finally, open a new terminal window, and ensure you are in the main project folder. From the terminal window, run the following command:

$ npm run webpack 
This command will process the client-side files creating the polyfills.js, vendor.js and app.js files. The command will not exit. Rather, it will run in watch mode, reprocessing the client-side files each time they are modified and saved. When running the application in Step 10, a new terminal window will need to be opened.

Now the client-side files are complete. It's time to run the application.

Step 10 – Run the Hello World Application

You have done a lot of work to get this far. No doubt, it's a lot of setup and configuration on the server and client, but once it's done, it's done. Adding additional server code and client code is simple to accomplish, allowing the real power of these technologies to shine through. To run the application, press F5 or open the Debug Panel by clicking the Bug sidebar icon to open the Debug Panel, and then clicking the Play Button at the top of the Debug Panel. When launched, .NET will execute the server-side web application within the Kestrel Development Web Server, and your default Web Browser will displaythe Hello World Angular 2 Application.

If you are using an editor other than Visual Studio Code or you simply prefer to run the application independently of the editor, perform the following steps:

  1. Open a terminal, and change to the folder.
  2. From the terminal window, run the following command:

    $ dotnet run
  3. Open a web browser, and navigate to http://localhost:5000.

Next Steps

Now that the server-side project is configured and running, the actual coding of the Widgets application can begin. In the following tutorials, additional .NET and Angular 2 code will be added to build a web application complete with tables, forms, basic CRUD (create, read, update, delete) operations, and a fully working REST service.

Author: Eric Greene, one of Accelebrate's instructors

 

In-Depth Angular Training

For in-depth Angular training, click here to view all of
Accelebrate's Angular training courses for you and your staff.

Contact Us:

Accelebrate’s training classes are available for private groups of 3 or more people at your site or online anywhere worldwide.

Don't settle for a "one size fits all" public class! Have Accelebrate deliver exactly the training you want, privately at your site or online, for less than the cost of a public class.

For pricing and to learn more, please contact us.

Contact Us Train For Us

Toll-free in US/Canada:
877 849 1850
International:
+1 678 648 3113

Toll-free in US/Canada:
866 566 1228
International:
+1 404 420 2491

925B Peachtree Street, NE
PMB 378
Atlanta, GA 30309-3918
USA

Subscribe to our Newsletter:

Never miss the latest news and information from Accelebrate:

Microsoft Gold Partner

Please see our complete list of
Microsoft Official Courses

Recent Training Locations

Alabama

Huntsville

Montgomery

Birmingham

Alaska

Anchorage

Arizona

Phoenix

Tucson

Arkansas

Fayetteville

Little Rock

California

San Francisco

Oakland

San Jose

Orange County

Los Angeles

Sacramento

San Diego

Colorado

Denver

Boulder

Colorado Springs

Connecticut

Hartford

DC

Washington

Florida

Fort Lauderdale

Miami

Jacksonville

Orlando

Saint Petersburg

Tampa

Georgia

Atlanta

Augusta

Savannah

Idaho

Boise

Illinois

Chicago

Indiana

Indianapolis

Iowa

Ceder Rapids

Des Moines

Kansas

Wichita

Kentucky

Lexington

Louisville

Louisiana

Baton Rouge

New Orleans

Maine

Portland

Maryland

Annapolis

Baltimore

Hagerstown

Frederick

Massachusetts

Springfield

Boston

Cambridge

Michigan

Ann Arbor

Detroit

Grand Rapids

Minnesota

Saint Paul

Minneapolis

Mississippi

Jackson

Missouri

Kansas City

St. Louis

Nebraska

Lincoln

Omaha

Nevada

Reno

Las Vegas

New Jersey

Princeton

New Mexico

Albuquerque

New York

Buffalo

Albany

White Plains

New York City

North Carolina

Charlotte

Durham

Raleigh

Ohio

Canton

Akron

Cincinnati

Cleveland

Columbus

Dayton

Oklahoma

Tulsa

Oklahoma City

Oregon

Portland

Pennsylvania

Pittsburgh

Philadelphia

Rhode Island

Providence

South Carolina

Columbia

Charleston

Spartanburg

Greenville

Tennessee

Memphis

Nashville

Knoxville

Texas

Dallas

El Paso

Houston

San Antonio

Austin

Utah

Salt Lake City

Virginia

Richmond

Alexandria

Arlington

Washington

Tacoma

Seattle

West Virginia

Charleston

Wisconsin

Madison

Milwaukee

Alberta

Edmonton

Calgary

British Columbia

Vancouver

Nova Scotia

Halifax

Ontario

Ottawa

Toronto

Quebec

Montreal

Puerto Rico

San Juan

© 2013-2019 Accelebrate, Inc. All Rights Reserved. All trademarks are owned by their respective owners.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.