Angular 2 and ASP.NET Core MVC

By the end of this post you will be able to integrate Angular 2 into an ASP.NET Core MVC Application (MVC page using both Razor and Angular 2)

Both Angular 2 and .NET Core have been RTM for a little while now. So I've been keen to get them working together.
There are plenty of examples online of how to create a .NET Core Web API and have an Angular 2 SPA talk to it. That's great, however not all Web Applications are SPAs and a lot of organisations wont re-write their applications just to reap the benefits of Angular 2.
At the time of writing I couldn't find any examples of integrating Angular 2 into a new/existing MVC page.

Theoretically most of this process will work with any html page (apart from the obvious C#/Razor bits). I'm assuming you have Visual Studio installed (Community Edition is free after all) - if not
you will be able to get "most of the way" through this guide, however you'll need the "NodeJS bits" that I will be stripping out (as VS auto runs some NodeJS commands for us).

I'm going to show how you can take a section of your MVC page and have Angular 2 control content in that! Without having to re-write your server-rendered web app to a SPA.

For the purposes of this demonstration I'm going to start off with a new ASP.NET Core project.

The source code can be found on GitHub

First off...

Create a blank ASP.NET Core MVC project.

alt

alt

Good job! We now have an empty MVC application.

Lets introduce Angular 2

Now we're going to include Angular 2 in the project. You could add the Angular 2 JavaScript files to your project and reference them from the _Layout.cshtml page, however...we know how to do that. We're here to learn right? So we'll use package.json (NodeJS) through Visual Studio.
(For deployment scenarios you really have to have a think about your build process and it you want to include NodeJS into that, or alternatively, reference them through a CDN)

To get hold of a package.json file, you'll need to Right-Click your Project, then choose Add > New Item, you're now looking for npm configuration file as below.

alt

Click Add and we now have a package.json in the root of our Web Application.

You'll need to create your own or borrow the quickstart "seed" tsconfig.json file.
Take a copy of tsconfig.json. If you're using external typings, create or borrow a typings.json file. Make sure the files are new .json files in the root of your project.

The tsconfig.json is TypeScript Configuation - this allows us to set a bunch of options for our TypeScript compiler. e.g. It can allow you to be more/less strict on the TypeScript you write.

The typings.json is TypeScript Declaration File - this gives us definitions for "Non-TypeScript libraries" so we get nice auto-completion and TypeSafety. The one-stop-shop where these definitions live is DefinitelyTyped

Choose the package.json tab and take a copy of the text inside! (there's some faff in here that we wont be needing because we're using Visual Studio so we'll strip that out).
UPDATE: copy the package.json from here or alternatively, run the Angular-CLI (this seems to be the way the Angular team want you to go) from here then copy/paste the package.json into your project directory. You could run the Angular-CLI commands in your project directory, however it installs a node server and a lot of other stuff we wont need - since we're using .NetCore.

Make sure you reference the latest version of Angular (and it's components) in the package.json.

Paste it inside package.json and it should look like this:

alt

If you're using Visual Studio we're going to remove a few things...

First off we don't need anything referencing "lite-server" - we're not going to be using NodeJS as a web server. So get rid!
Second, remove everything in "devDependencies" - Visual Studio will be taking care of TypeScript transpilation so NodeJS needent care.
Lastly, I'm not going to be using "bootstrap" or "angular-in-memory-web-api" so remove those too!

The result should look like this:

alt

Save the file and Visual Studio will run "npm install" for you which will install all the pacakges and typings. You should see a "typings" folder appear which indicates the "postinstall" script has run successfully.

(NOTE: at the time of writing Visual Studio failed to npm install the typings after installing the packages. To ensure they were installed as these are needed for building the Application, I quit Visual Studio cmd'd to the root of the project and did npm install - this correctly ran the post-install
typings install.....I can only assume that Visual Studio has some kind of lock on a file and throws out some strange error messages)

The last step is to introduce SystemJS - which is a "Universal dynamic module loader" - basically, it lets you specify your app's JavaScript files through the systemjs.config.js file which you serve to the browser, then it looks inside that for references to your JS files and then downloads them.

Personally I wouldn't use SystemJS in a "real app" (for me - the added complexity and "magic" isn't worth it) - but since this is only a demo, I'm going to jump right in as it gets us started reasonably easy (an alternative would be to use WebPack, or even just create your bundles at build time and be done with it - your mileage may vary so once you're familiar with Angular 2 you can start experimenting with these different tools)

I've put SystemJS in a folder all on its own in the project root and put the systemjs.config.js file inside.

Let's write some Angular 2

I'm trying to keep this post reasonably light so we're only going to get a very very simplistic Angular 2 example working.
We're going to be showing a text input on screen, that when the user types in text and presses enter, we'll trigger a window.alert()

Create a folder in the project root called "app" - in here we're going to put our Angular 2 TypeScript files.

For the sake of simplicity I'd suggest copying the TypeScript files found in the GitHub Repo
Having a quick read through the Angular 2 code, most of it is the "boiler plate" you get from the Angular 2.io website.
All I've done is defined a new component called Searchbox and told my app to load it. Searchbox defines a keyup.enter event and sends that to the displayAlert() function in the SearchBoxComponent class.

Here's the implementation of searchbox.component.ts

Lastly we need to include the Angular 2 application on one of our pages, I've stuck the <my-app></my-app> declaration in the Index.cshtml page for now.

Getting JavaScript to the browser

There are a few steps we need to take to get our JavaScript to the browser...

  1. Compile the TypeScript to JavaScript (if you're not using Visual Studio then you'll have to do this through NPM...for example)
  2. Move the required JavaScript files to the wwwroot folder to be served
  3. Configure SystemJS to find the JavaScript files

1 - Compiling

If you're using Visual Studio then you're in luck! It takes care of TypeScript compilation automatically.
All you need to do is ensure that you're tsconfig.json file looks something like this

The important parts being rootDir (where the actual .ts files are) and outDir (where you want the compiled files to go).
I've also set compileOnSave to true this will mean that I can make a change to a TypeScript file, save, refresh the browser and see my changes.

2 - Moving files around

I'm going to use Gulp to move files around when building the project. Note you could use Grunt, npm-scripts or even XCOPY - remember use what YOU'RE comfortable with and what suits YOUR needs!

Add gulp to your package.json (it's installed through NPM), by adding the following to the package.json file

"devDependencies": {
    "gulp": "3.9.1"
}

Add a new gulpfile.js to your project by Right-Clicking and then...
Add > New Item > .NET Core > Gulp Configuation file
Save that and copy/paste the below code.

(I've commented to give an idea of what it's doing)

The first line of the gulpfile is a Visual Studio Directive which says "before you run a build, run the gulp task 'beforeBuild'"

3 - Configuring SystemJS

If you're not using SystemJS then you can skip this step (as you've most likely included all the necessary JavaScript files in your page - using script tags)

Copy/paste the following SystemJS config file - I've added comments to the file again to give an overview of what things are.

Run IT!

If you hit F5 to run your project (depending on where you've put your <my-app></my-app> component) you should see a screen like the following...

Done!

Spotted the text box at the top of the screen?! It's not pretty, but that is the foundation of getting Angular 2 running within ASP.NET Core MVC.

Conclusion

Server side rendering of our page content works, and it's great for SEO, but sometimes you need a section of the page to be more "dynamic", e.g. it might fetch content from the server or perform polling and display results. A full-page refresh for those instances are extraneous.
For simple "dynamic" sections of the page, then plain JavaScript or even jQuery might be the way to go......but for complex widgets/components - Angular 2 definitely shines for those accustomed to Strong-Types and OO (Object-Oriented) languages.

Shout at me on Twitter/Comments below on what you'll be building now you can use Angular 2 and ASP.NET Core MVC together. Also let me know if you have any improvements/criticisms......we're all here to learn!

ryansouthgate

Software developer, living in Coventry, loves .Net, JavaScript and learning new languages.

Coventry