The purpose of this post is to establish ourselves with a working environment geared towards development on ASP.NET Core 1.0 through Visual Studio 2015. I will walk through creating an Angular2 Single Page Application with MVC 6, Web API 2 and TypeScript. The sample application is available here on my github page.
A quick nod of approval before we get started
As a community of early adopters it is gratifying to see collaborations betwixt Microsoft and Google, finally “we can all get along”.
These collaborations are exciting and certainly influential – my only hope is that we see more of these collaborations and other large industry leaders follow their example!
There are several things that you’ll need before we dive into writing code. We should take a moment to familiarize ourselves with some of the new core concepts as well as ensuring that we have our IDE correctly installed and configured.
Install Visual Studio 2015
It all starts with your favorite IDE, mine being VS (of course, if that wasn’t obvious). You can download the community version of it here. The nice thing about the community version is that it is entirely free! Once you have it installed you’re ready to begin setting up your web solution. Finally, as a prerequisite you should at the very least be familiar with .NET MVC.
A few noteworthy mentions
project.json is the replacement for the
*.csproj file. The main difference is the file format – you’ve probably been noticing the shift away from XML and the movement to the preferred JSON format as it is superior.
The wwwroot folder now acts as the directory in which your web site will be served from. Instead of your entire solution directory acting as the file structure, now this single folder and its sub directories act as the root of the application.
While Node.js and its corresponding package manager, namely “npm” are part of the install for Visual Studio 2015 – it installs with
1.4.9 which is unfortunately an outdated version . Angular2 might play nicer with a later version of npm.
” Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world!
Let’s address this now, so that we do not run into issues once we start writing code. Install the latest version of Node.js here. Once installed navigate to the following directory:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\External\
npm.cmd file in your favorite text editor (running as Administrator) and replace the contents of this file with the following:
@"C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" %*
Now Visual Studio 2015 will utilize the npm version that was installed from the aforementioned steps.
ASP.NET Core 1.0
At this point you are probably wondering, “what is ASP.NET Core 1.0 and what happened to ASP.NET 5?”. These are both great questions, and to answer them ASP.NET 5 has been renamed more appropriately. Since it was completely rewritten from the ground up, why not rename and version it? For the remainder of this tutorial, if you happen to see reference to ASP.NET 5 think of it as ASP.NET Core 1.0 and use them interchangeably for now. But don’t take my word for it, check out Scott Hanselman’s post “ASP.NET 5 is dead“.
” ASP.NET 5 is a new open-source and cross-platform framework for building modern cloud-based Web applications using .NET.
With .NET 4.6 you get C# 6. C# 6 is something that I have personally been looking forward to. I’m not sure I share the same level of excitement as I did with .NET 4.5 and its asynchronous programming model support, but excited nonetheless! Additionally, we are now going to start harnessing ASP.NET Core 1.0.
” ASP.NET 5 applications are built/ran using the new .NET Execution Environment (DNX), and every ASP.NET 5 project is a DNX project.
DNX is an acronym that stands for .NET Execution Environment. It is basically just an SDK within the context of Visual Studio, but also acts as the runtime environment in which your ASP.NET Core 1.0 applications execute.
Accompanying DNX is the DNU and DNVM CLI’s.
- DNU, .NET Utility
- DNVM, .NET Version Manager
For more details on these command line interfaces please visit here.
We should be familiar enough with some of the core concepts such that we can finally begin by creating a new ASP.NET Core 1.0 web application. From within Visual Studio 2015, select
File → New → Project. Then from within the New Project dialog navigate and select
Installed → Templates → Visual C# → Web → ASP.NET Web Application – select “Ok”.
Visual Studio 2015 now groups templates by .NET Framework version, notice ASP.NET 5 applications are separated and beneath .NET Framework 4.6.1. Additionally, notice when you select the ASP.NET 5 templates that the MVC and Web API check-boxes are disabled – the reason being that they are now unified in ASP.NET Core 1.0.
Personally, I’m thrilled that there is no longer a need to have Web API controllers inherit
ApiController and MVC controllers inherit
Controller – more about this later…
” There can be only one.
Yes, that is a Highlander reference! But it’s actually appropriate because there should be only one
Controller – not to mention the seemingly countless other duplicate classes that overlapped with
Select the “Empty” template, and let’s continue – your solution should now resemble the figure below:
We can delete the
Project_Readme.html file as it is not needed. Now let’s add some standard MVC scaffolding, you should have the following for our starting point:
All that is needed from the previous step was the folder structure and several built-in templates.
|Folder||Add New Item Step|
Of the multiple items we have added at this point, there are only three that we need to alter from the default template provided. First the
_ViewImports.cshtml, it should resemble the content below – and simply enables tag helpers.
_Layout.cshtml that references our script tags and invokes the
Index.cshtml which is rendered as the body of the layout and introduces an
app element that will be detailed later.
Now let’s get our webroot structure solidified, expand the
wwwroot folder and add the folders depicted below. We will add to these later.
project.json file and let’s paste in the following JSON. This will pull in the required dependencies we need for our starter application. The ‘dependencies’ are simply NuGet package references – be sure to paste everything defined below.
If you’re familiar with OWIN then the next steps will be very straightforward. Open the
Startup.cs file., and let’s paste in some more source and discuss its purpose.
You might have noticed that in addition to a
public void Configure method there is now a
public void ConfigureServices method as well. Additionally, the
Configure method now expects two new parameters,
The typical usage pattern is that you invoke an
Add* extension method in the
ConfigureServices operation to add a service for consumption, while in the
Configure operation you invoke the corresponding
Use* extension method.
The pattern becomes obvious when you study the
ConfigureServices source, notice how we are adding Glimpse and MVC to the
” Glimpse provides real time diagnostics & insights to the fingertips of hundreds of thousands of developers daily.
As you see below, within the
Configure method now invokes the two corresponding methods –
Avoid crossing your eyes while dotting your “t’s”
In other words, pay attention to what it is that you’re doing. A lot of what we have done thus far was simple MVC related and server-side, let’s now shift the attention to the client-side and how Angular2, TypeScript, Task Runners and npm will play a role.
package.json, but first we need to create one.
Right click on project and select
Add → New Item. From the Add New Item dialog select
Installed → Client-side → NPM Configuration File. This will add the
package.json file, replace its contents with the following:
Note the different types of dependencies from the highlighted source above, one set of dependencies is explicitly for development only – meaning it is not part of what is served to clients in response to a web request. Among these development dependencies you’ll notice gulp a lot.
With the introduction of Visual Studio 2015 the notion of Task Runners is now supported. The Task Runner Explorer is a new window in which your task runner file tasks can be bound to IDE events.
Gulp is one of two task runners now fully integrated and supported in the IDE. Gulp is a pre-processor for content delivery and if you’re familiar with the concept of MVC bundling, this is pretty much the same thing. Multiple files are input and the files are checked for errors, minified and delivered as a single file to the client.
Let’s add the following
gulpfile.js to our project,
Add → New Item. From the Add New Item dialog select
Installed → Client-side → Gulp Configuration File.
Most (if not all) of the Gulp source code should be easy to read and comprehend. We are simply defining several tasks that can be bound to IDE events. We require several JS libraries that were referenced in our
devDependencies, then we simply author the desired functionality into each named task by utilizing the fluent API that Gulp provides for chaining methods together.
There are four events that you can tether tasks to, three of which are technically build-events and the other is not.
||Executes bound gulp task(s) before compilation|
||Executes bound gulp task(s) after compilation|
||Executes bound gulp task(s) after the Clean finishes|
||Executes bound gulp task(s) while project is opening|
We have bound our
default task to the “Before Build” event. These tasks copy over the dependencies our application relies on to run.
Angular2 is simply the second version of the AngularJS.
” Angular is a development platform for building mobile and desktop web applications.
wwwroot we expect the following folder structure, where the
wwwroot\app is the only place in which we manually manipulate source code. The other folders should be left alone as our Gulp task will copy over our dependencies as needed into the other directories.
. ├── app [ working directory ] │ └── components ├── css ├── fonts ├── images └── js └── angular2
Let’s start by adding our
boot.ts file. This file will bootstrap our main entry point for Angular2 to initialize and act on. Additionally this will define our Router and Http Providers. The MVC
_Layout.cshtml has a script tag that invokes this file.
We will now need to define our
AppComponent, add a new TypeScript file namely
app.component.ts to the
wwwroot\app directory. It should contain the following:
AppComponent created, we’ll need to create our
app.html. This will serve as the template for the menu structure and view-port if you will of our application. There is a direct correlation that I need to call attention to, for each
RouteDefinition there is a menu item in our HTML that is rendered. When a route-link is clicked Angular2 loads the component declared in the route definition and renders its HTML in place of the
Static HTML ‘templateUrl’
For this sample application, I will demonstrate how to utilize static
.html and MVC partial view pre-processing for our Angular2 component “templateUrl’s”. Additionally, I’ll demonstrate a simply Web API 2 call as well. You may have noticed that we have several components that we have references to within the
app.component that we have yet to create, let’s do that now.
static.html under the
selector is actually the CSS selector Angular2 uses to find the DOM element in which the
templateUrl will replace once rendered. Here is the
.html, as you can see very simple.
MVC Partial View ‘templateUrl’
We can utilize the power of MVC’s pre-processing capabilities and have a
Controller who is responsible for serving up partial views. This is great since we can then utilize MVC templating in conjunction with Angular2 templating. Add yet another new TypeScript file named
Notice that our syntax has changed ever so slightly for the
templateUrl, this is actually pointing to an MVC partial view that we’re going to create right now. Create a new folder under
Views, name it “Partial”. Then add a new MVC View Page, naming it
The markup is nearly identical, but the implementation is vastly different. We’ll need the corresponding
Controller to serve up these requests. Add a
PartialController with two entry points, the second of which will become obvious in our next step.
I love the one-liner syntax that a simple lambda expression provides with C# 6!
Web API 2 and Angular2’s Http
Adding another MVC View Page to our newly created
Views\Partial directory, let’s call it
Numbers.cshtml. The markup has several key bindings to an Angular2 component that we will need to define.
Back over in our
wwwroot\app\components, we will need to obviously add our
api.component.ts but also an
api.service.ts that will encapsulate our Web API 2 call via Angular2’s Http library.
ApiComponent gets injected with an instance of our
ApiService and defines a few simple members that are bound to the
I’m simply ecstatic that there was a change to move away from the
Promise model to the
Observable model instead. Anytime I get to work with Reactive Programming paradigm, I learn something new. Angular2’s Http library is based on the observable programming model and relies on RxJS. I invite you to read how Angular2 works with
observables here but simply put, you subscribe to the
Observable passing it the
observerOrNext (and optionally
All we need now is a Web API 2 controller that will serve up the HttpGet that
ApiService expects at “api/random”. Fortunately for us this has been dramatically simplified with ASP.NET Core 1.0. No more woes with
” Now, you can create a single web application that handles the Web UI and data services without needing to reconcile differences in these programming frameworks.
Notice that there is no
ApiController inheritance, and both the MVC and Web API controllers are simply inheriting from
You should be able to clone the repository locally, build it and play around. I encourage you to do so and hope that you find the sample source fun and the tutorial surrounding it useful. Today we discussed some of the capabilities of ASP.NET Core 1.0 (previously known as ASP.NET 5), MVC 6, Web API 2, Angular2 and TypeScript. I leave you with one question, “tomorrow, what will you do with it?”.