ASP.Net 5: Jump Start to AngularJS With MVC 6 Web API

Introducing AngularJs

Before we dig further let's talk about a quick overview of AngularJs and Web API in MVC 6.

AngularJs is a client-side MVC framework written in JavaScript. It runs in a web browser and greatly helps us (developers) to write modern, single-page, AJAX-style web applications. It is a general purpose framework, but it shines when used to write CRUD (Create Read Update Delete) type web applications.

Introducing Web API

ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework. In ASP.NET 5, Web API is now part of MVC 6.

If you are new to ASP.NET 5 then I would suggest you to read the following articles below to learn more about the new features in ASP.NET:

Creating an ASP.NET 5 Project

To start fire up Visual Studio 2015 and create a new ASP.NET 5 project by selecting File > New Project. In the dialog, under Templates > Visual C#, select ASP.NET Web Application as shown in the figure below:


Figure 1: New Project dialog

Name your project to whatever you like and then click OK. For the example I named the project as “AngularJS101”. Now after that you should be able to see the “New ASP.NET Project” dialog:


Figure 2: New ASP.NET Project dialog

Now select ASP.NET 5 Preview Empty template from the dialog above. Then click OK to let Visual Studio generate the necessary files and templates needed for you. You should be able to see something as in the following:


Figure 3: New default ASP.NET 5 Empty project structure

Adding the Scripts folder

The next thing to do is to create a new folder called “Scripts”. This folder will contain all the JavaScript files needed in our application:


Figure 4: The Scripts folder

Getting the Required Packages

ASP.NET 5 now supports three main package managers: NuGet, NPM and Bower.

Package Manager

A package manager enables you to easily gather all resources that you need for building an application. In other words, you can use the package manager to automatically download all the resources and their dependencies instead of manually downloading project dependencies such as jQuery, Bootstrap and AngularJs from the web.

NuGet: NuGet manages .NET packages such as Entity Framework, ASP.NET MVC and so on. You typically specify the NuGet packages that your application requires within a project.json file.

NPM: NPM is one of the newly supported package managers in ASP.NET 5. This package manager was originally created for managing packages for the open-source NodeJS framework. The package.json is the file that manages your project's NPM packages.

Bower: Bower is another supported package manager in ASP.NET 5. It was created by Twitter that is designed to support front-end development. You can use Bower to manage client-side resources such as jQuery, AngularJs and Bootstrap.

For this example we need to use NPM to install the resources we need in our application such as Grunt and the Grunt plugins. To do this just right-click in the Project (in this case AngularJS101) and select Add > New Item. In the dialog select NPM configuration file as shown in the figure below:


Figure 5: Adding NPM config file

Click Add to generate the file for you. Now open package.json file and modify it by adding the following dependencies:

  1. {  
  2.    "version""1.0.0",  
  3.    "name""AngularJS101",  
  4.    "private"true,  
  5.    "devDependencies": {  
  6.    "grunt""0.4.5",  
  7.    "grunt-contrib-uglify""0.9.1",  
  8.    "grunt-contrib-watch""0.6.1"  
  9.    }  
  10. }
Notice that you get Intellisense support while you edit the file. A matching list of NPM package names and versions shows as you type.

In package.json file, from the code above, we have added three (3) dependencies named grunt, grunt-contrib-uglify and grunt-contrib-watch NPM packages that are required in our application.

Now save the package.json file and you should be able to see a new folder under Dependencies named NPM as shown in the following:


Figure 6: NPM dependencies

Right-click on the NPM folder and select Restore Packages to download all the packages required. Note that this may take a bit to finish the download so just be patient and wait ;). Then the grunt, grunt-contrib-uglify and grunt-contrib-watch NPM packages should now be installed as shown in the following:


Figure 7: Installing NPM dependencies

Configuring Grunt

Grunt is an open-source tool that enables you to build client-side resources for your project. For example, you can use Grunt to compile your LESS or Saas files into CSS. Adding to that, Grunt can also be used to minify CSS and JavaScript files.

In this example, we will use Grunt to combine and minify JavaScript files. We will configure Grunt so that it will take all the JavaScript files from the Scripts folder that we created earlier, combine and minify the files and finally save the results to a file named app.js within the wwwroot folder.

Now right-click on your project and select Add > New Item. Select Grunt Configuration file from the dialog as shown in the figure below:


Figure 8: Adding Grunt config file

Then click Add to generate the file and then modify the code within the Gruntfile.js file so it will look like this:
  1. module.exports = function (grunt) {  
  2.    grunt.loadNpmTasks('grunt-contrib-uglify');  
  3.    grunt.loadNpmTasks('grunt-contrib-watch');  
  4.   
  5.    grunt.initConfig({  
  6.       uglify: {  
  7.          my_target: {  
  8.          files: { 'wwwroot/app.js': ['Scripts/app.js''Scripts/**/*.js'] }  
  9.       }  
  10. },  
  11. watch: {  
  12.    scripts: {  
  13.       files: ['Scripts/**/*.js'],  
  14.          tasks: ['uglify']  
  15.       }  
  16.    }  
  17. });  
  18.    grunt.registerTask('default', ['uglify''watch']);  
  19. };
The code above contains three sections. The first one is used to load each of the Grunt plugins that we need from the NPM packages that we configured earlier. The initConfig() is responsible for configuring the plugins. The Uglify plugin is configured so that it combines and minifies all the files from the Scripts folder and generate the result in a file named app.js within wwwroot folder. The last section contains the definitions for your tasks. In this case we define a single "default" task that runs "uglify" and then watches for changes in our JavaScript file.

Now save the file and let's run the Grunt file using Visual Studio Task Runner Explorer. To do this, go to View > Other Windows > Task Runner Explorer in Visual Studio main menu. In the Task Runner Explorer be sure to hit the refresh button to load the tasks for our application. You should see something like this:


Figure 9: The Visual Studio Task Runner Explorer

Now right-click on the default task and select Run. You should be able to see the following output:


Figure 10: Running Task Runner

Configuring ASP.NET MVC

There are two main files that we need to modify to enable MVC in our ASP.NET 5 application.

First, we need to modify the project.json file to in include MVC 6 under dependencies:
  1. "webroot""wwwroot",  
  2. "version""1.0.0-*",  
  3. "dependencies": {  
  4.    "Microsoft.AspNet.Server.IIS""1.0.0-beta3",  
  5.    "Microsoft.AspNet.Mvc""6.0.0-beta3"  
  6.    },  
  7. "frameworks": {  
  8. "aspnet50": { },  
  9. "aspnetcore50": { }  
  10. },  
Be sure to save the file to restore the packages required. The project.json file is used by the NuGet package manager to determine the packages required in your application. In this case we've added Microsoft.AspNet.Mvc.

Now the last thing is to modify the Startup.cs file to add the MVC framework in the application pipeline. Your Startup.cs file should now look like this:
  1. using System;  
  2. using Microsoft.AspNet.Builder;  
  3. using Microsoft.AspNet.Http;  
  4. using Microsoft.Framework.DependencyInjection;  
  5. namespace AngularJS101  
  6. {  
  7.    public class Startup  
  8.    {  
  9.       public void ConfigureServices(IServiceCollection services)  
  10.       {  
  11.          services.AddMvc();  
  12.       }  
  13.       public void Configure(IApplicationBuilder app)  
  14.       {  
  15.          app.UseMvc();  
  16.       }  
  17.    }  
The ConfigureServices() method is used to register MVC with the ASP.NET 5 built-in Dependency Injection Framework (DI). The Configure() method is used to register MVC with OWIN.

Adding Models

The next step is to create model that we can use to pass data from the server to the browser /client. Now create a folder named “Models” under the root of your project. Within the “Models” folder, create a class named “DOTAHero” and add the following code below:
  1. using System;  
  2.   
  3. namespace AngularJS101.Models  
  4. {  
  5.    public class DOTAHero  
  6.    {  
  7.       public int ID { getset; }  
  8.       public string Name { getset; }  
  9.       public string Type { getset; }  
  10.    }  
  11. }
Create another class called “HeroManager” and add the following code below:
  1. using System.Collections.Generic;  
  2. using System.Linq;  
  3. namespace AngularJS101.Models  
  4. {  
  5.    public class HeroManager  
  6.    {  
  7.       readonly List<DOTAHero> _heroes = new List<DOTAHero>() {  
  8.       new DOTAHero { ID = 1, Name = "Bristleback", Type="Strength"},  
  9.       new DOTAHero { ID = 2, Name ="Abbadon", Type="Strength"},  
  10.       new DOTAHero { ID = 3, Name ="Spectre", Type="Agility"},  
  11.       new DOTAHero { ID = 4, Name ="Juggernaut", Type="Agility"},  
  12.       new DOTAHero { ID = 5, Name ="Lion", Type="Intelligence"},  
  13.       new DOTAHero { ID = 6, Name ="Zues", Type="Intelligence"},  
  14.       new DOTAHero { ID = 7, Name ="Trent", Type="Strength"},  
  15.    };  
  16.    public IEnumerable<DOTAHero> GetAll { get { return _heroes; } }  
  17.   
  18.    public List<DOTAHero> GetHeroesByType(string type) {  
  19.    return _heroes.Where(o => o.Type.ToLower().Equals(type.ToLower())).ToList();  
  20. }  
  21. public DOTAHero GetHeroByID(int Id) {  
  22.    return _heroes.Find(o => o.ID == Id);  
  23.    }  
  24. }  
  25. }
The HeroManager class contains a readonly property that contains a list of heroes. For simplicity, the data is obviously static. In real scenario you may need to get the data in a storage medium such as database or any files that stores your data. It also contain a GetAll property that returns all the heroes and a GetHeroesByType() method that returns a list of heroes based on the hero type and finally a GetHeroByID() method that returns a hero based on ID.

Adding Web API Controller

For this specific example, we will be using Web API for passing data to the browser/client.

Unlike previous versions of ASP.NET, MVC and Web API controllers used the same controller base class. Since Web API is now part of MVC 6 then we can start creating Web API controllers because we already pulled the required NUGet packages for MVC 6 and configured MVC 6 in startup.cs.

Now add an “API” folder under the root of the project:


Figure 11: The API folder

Then add a Web API controller by right-clicking the API folder and selecting Add > New Item. Select Web API Controller Class and name the controller as “HeroesController” as shown in the figure below:


Figure 12: Adding Web API controller

Click Add to generate the file for you. Now modify your HeroesController class by adding the following code below:
  1. using System.Collections.Generic;  
  2. using Microsoft.AspNet.Mvc;  
  3. using AngularJS101.Models;  
  4.   
  5. namespace AngularJS101.API.Controllers  
  6. {  
  7.    [Route("api/[controller]")]  
  8.    public class HeroesController : Controller  
  9.    {  
  10.       // GET: api/values  
  11.       [HttpGet]  
  12.       public IEnumerable<DOTAHero> Get()  
  13.       {  
  14.          HeroManager HM = new HeroManager();  
  15.          return HM.GetAll;  
  16.       }  
  17.   
  18.       // GET api/values/7  
  19.       [HttpGet("{id}")]  
  20.       public DOTAHero Get(int id)  
  21.       {  
  22.          HeroManager HM = new HeroManager();  
  23.          return HM.GetHeroByID(id);  
  24.       }  
  25.   
  26.    }  
  27. }
At this point we will only be focusing on GET methods to retrieve data. The first GET method returns all the heroes available by calling the GetAll property found in HeroManager class. The second GET method returns a specific hero data based on the ID.

You can test whether the actions are working by running your application in the browser and appending the /api/heroes in the URL. Here are the outputs for both GET actions.

Route: /api/heroes


Figure 13: GetAll result

Route: /api/heroes/7


Figure 14: GetHeroByID result

Creating the AngularJs Application

Visual Studio 2015 includes templates for creating AngularJs modules, controllers, directives and factories. For this example we will be displaying the list of heroes using an AngularJs template.

Adding an AngularJs Module

To get started let's create an AngularJs module by right-clicking on the Scripts folder and selecting Add > New Item. Select AngularJs Module as shown in the figure below.


Figure 15: Adding AngularJs Module

Click Add to generate the file and copy the following code for our AngularJs module:
  1. (function () {  
  2. 'use strict';  
  3.   
  4. angular.module('heroesApp', [  
  5.    'heroesService'   
  6.    ]);  
  7. })();
The code above defines a new AngularJs module named “heroesApp”. The heroesApp has a dependency on another AngularJs module named “heroesService” that we will create later in the next step.

Adding an AngularJs Controller

The next thing to do is to create a client-side AngularJs Controller. Create a new folder called “Controllers” under the Script folder as in the following:


Figure 16: AngularJs Controllers folder

Then right-click on the Controllers folder and select Add > New Item. Select AngularJs Controller using $scope as shown in the figure below:


Figure 17: Adding AngularJs Controller file

Click Add and copy the following code below within your heroesController.js file:
  1. (function () {  
  2.     'use strict';  
  3.   
  4.     angular  
  5.         .module('heroesApp')  
  6.         .controller('heroesController', heroesController);  
  7.   
  8.     heroesController.$inject = ['$scope','Heroes'];   
  9.   
  10.     function heroesController($scope, Heroes) {  
  11.         $scope.Heroes = Heroes.query();  
  12.     }  
  13. })();  
The code above depends on the Heroes service that supplies the list of heroes. The Heroes service is passed to the controller using dependency injection (DI). The $inject() method call enables DI to work. The Heroes service is passed as the second parameter to the heroesController() function.

Adding the Heroes Service

We will use an AngularJs Heroes service to interact with our data via Web API. Now add a new folder called “Services” within the Script folder. Right-click on the Services folder and select Add > New Item. From the dialog select AngularJs Factory and name it “heroesService.js” as in the following:


Figure 18: Adding AngularJs Factory file

Now click Add and then replace the generated default code with the following:
  1. (function () {  
  2.    'use strict';  
  3.    var heroesService = angular.module('heroesService', ['ngResource']);  
  4.    heroesService.factory('Heroes', ['$resource',  
  5.    function ($resource) {  
  6.       return $resource('/api/heroes', {}, {  
  7.       query: { method: 'GET'params: {}, isArray: true}  
  8.       });  
  9.       }  
  10.    ]);  
  11. })();
The code above basically returns a list of heroes from the Web API action. The $resource object does an AJAX request using a RESTful pattern. The heroesService is associated with the /api/heroes route on the server. This means that when you do a query against the service from your client-side code, the Web API HeroesController is invoked to return a list of heroes.

Adding an AngularJs Template

Let's add an AngularJs template for displaying the list of heroes. To do this we will need an HTML page to render in the browser. In the wwwroot folder add a new HTML page and name it “index” for simplicity. Your application structure should now look like this:


Figure 19: Adding the Index.html page

The wwwroot folder is a special folder in your application. The purpose is that the wwwroor folder should contain all the contents of your website such as HTML files and images needed for your website.

You should not place any of your source code within the wwwroot folder. Instead source codes such as MVC controller's source, model classes and unminified JavaScript and LESS files should be place outside of the wwwroot folder.

Now replace the contents of the index.html with the following:
  1. <!DOCTYPE html>  
  2.    <html ng-app="heroesApp">  
  3.       <head>  
  4.          <meta charset="utf-8" />  
  5.             <title>DOTA 2 Heroes</title>  
  6.             <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>  
  7.             <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-resource.js"></script>  
  8.             <script src="app.js"></script>  
  9.       </head>  
  10.       <body ng-cloak>   
  11.          <div ng-controller="heroesController">  
  12.             <h1>DOTA Heroes</h1>  
  13.                <table>  
  14.                   <thead>  
  15.                      <tr>  
  16.                         <th>ID</th>  
  17.                         <th>Name</th>  
  18.                         <th>Type</th>  
  19.                      </tr>  
  20.                   </thead>  
  21.                   <tbody>  
  22.                      <tr ng-repeat="hero in Heroes">  
  23.                         <td>{{hero.ID}}</td>  
  24.                         <td>{{hero.Name}}</td>  
  25.                         <td>{{hero.Type}}</td>  
  26.                      </tr>  
  27.                   </tbody>  
  28.                </table>  
  29.          </div>  
  30.       </body>  
  31.    </html> 
There are several things to point out from the markup above.

The <html> element is embedded with the ng-app directive. This directive associates the heroesApp with the HTML file.

In the <script> section, you will see that I use Google CDN for referencing AngularJs and related libraries. Besides being lazy, it's my intent to use CDN for referencing standard libraries such as jQuery, AngularJs and Bootstrap to boost application performance. If you don't want to use CDN then you can always install AngularJs packages using Bower.

The <body> element is embedded with the ng-cloak directive. This directive hides an AngularJs template until the data has been loaded in the page.

The <div> element within the <body> block is embedded with the ng-controller directive. This directive associates the heroesController and renders the data within the <div> element.

Finally, the ng-repeat directive is added to the <tr> element of the <table>. This will create a row for each data retrieved from the server.

Output

The following is the output of running the page and navigating to index.html:


Figure 20: Application output

That's it! I hope you will find this article useful and fun. Stay tuned for more!

Up Next
    Ebook Download
    View all
    Learn
    View all