Prerequisites
- Javascript
- C#
- MVC
- Visual Studio 2013 (Installed)
What is AngularJS? (Wiki)
AngularJS, commonly referred to as Angular, is an open-source web application framework maintained by Google and a community of individual developers and corporations to address many of the challenges encountered in developing single-page applications. Its goal is to simplify both development and testing of such applications by providing a framework for client-side model–view–controller (MVC) architecture.
Is Angular the right tool for your project?
- Do you have a lot of frontend data manipulation?
- Do you have less than 2000 records per page?
- You want to build a Single Page Application?
If your answer is yes, then I encourage you to use Angular. The MVC architecture helps you write clean, maintainable, and reusable code. When records exceed 2000, Angular becomes slow, so it’s discouraged to use it.
Where does Angular run?
Since Angular is a JavaScript framework, it runs on the client. Let me say that again, it runs on the client NOT on the server.
What about WebAPI?
This is what happened till now.
- Client requested your website
- Client got the related HTML,CSS, JavaScript (Including Angular)
- Angular is now running on Client listening and responding to events (click, state change etc..)
At this point life is beautiful, but we forgot to mention the small part where we fetch the data from the database. That’s the job of no other than WebAPI! Since Angular is a JavaScript Framework, naturally the most convenient way to read data is a JavaScript object (JSON, JavaScript Object Notation). WebAPI is a RESTful web service that just happens to return JSON (the luck!), it runs on the Server and waits for HTTP request (POST,GET …). Its job is to fetch data from the database and return it to the client as JSON (remember Angular wants the data as JSON).
HTTP POST/PUT and GET
- Use “GET” when you want to read (select) from the database.
- Use “POST/PUT” when you want to write (insert, update) to the database.
POST and GET Security
POST is NOT more secure than GET. Both are visible for an attacker…
The full picture
The red arrow represents the first phase.
- As noted before, the user calls your website (1)
- Your server response with the related HTML, CSS, and JavaScript (2)
- Angular starts running on the client side
The blue arrow represents the second phase
- Angular realizes it needs data from the database so it asks the WebAPI to provide this data (3)
- WebAPI goes to the database and asks for the data (4)
- Database Return the data (5)
- WebAPI reformats that data as JSON and sends it to Angular (6)
Angular, Getting our Hands Dirty!
In Visual Studio 2013, click on
- Click on "File"
- New => "Project"
- Choose "Web" => ""ASP.NET Web Application" => "Ok"
- Choose "Empty" => "change authentication" and remove authentication
- click on "Ok"
Now, create all the files and directories to have the below project structure.
Download the following libraries jQuery, Angular, Ui-Router, Bootstrap (not required) and add them to the project as seen in the below image.
Note we have an HTML file called Index, this will act like a MasterPage in ASP. Thus, Index.html will hold all the JavaScript and CSS references. So let’s dig into Index.html
/Index.html
<!DOCTYPE html>
<html ng-app="app"> <!-- this tell Angular to run -->
<head>
<title>Angular + WebAPI</title>
<script src="./Scripts/jquery.js"></script>
<script src="./Scripts/angular.js"></script>
<script src="./Scripts/angular-ui-router.js"></script>
<script src="./App/app.js"></script>
<script src="./App/controllers.js"></script>
<script src="./Scripts/bootstrap.min.js"></script>
<link rel="stylesheet" href="./Style/CSS/bootstrap.css" />
<link rel="stylesheet" href="./Style/CSS/style.css" />
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<ul class="nav navbar-nav">
<li>
<a href="#/">
Home
</a>
</li>
<li>
<a href="#/movies">
Movies
</a>
</li>
</ul>
</div>
</nav>
<div class="container">
<!--
Note the below ui-view attribute, not the id.
The content of the div will be replaces by
the view that is stated inside app.js
-->
<div id="ui-view" ui-view>
</div>
</div>
</body>
</html>
/App/app.js
angular.module('app',
[
'ui.router',
'app.controllers',
]
)
.config(['$stateProvider',
function ($stateProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: './View/Home.html'
})
.state('movies', {
url: '/movies',
templateUrl: './View/Movies.html',
controller: 'MoviesController'
})
.state('otherwise', {
url: '*path',
templateUrl: '/View/Error.html',
controller: 'ErrorCtrl'
});
}]
);
/App/controllers.js
angular.module('app.controllers', [])
.controller('MoviesController', function ($scope)
{
});
/View/Movies.html
<div class="row">
<h2>Movies</h2>
</div>
<div class="row">
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Director</th>
</tr>
</thead>
<tbody>
<tr>
<td>
1
</td>
<td>
Fight Club
</td>
<td>
David Fincher
</td>
</tr>
<tr>
<td>
2
</td>
<td>
Into The Wild
</td>
<td>
Sean Penn
</td>
</tr>
</tbody>
</table>
</div>
Adding the project to the IIS
Press the Windows Key and search for “IIS” which stands for (Internet Information Service). If you don’t have it you might need to install it.
- Expand “Sites”
- Right click on “Default Web Site” => and choose “Add Application”
- In the Alias, enter “angular”
- Point the physical path to your Project (not solution) directory.
X:\ CodeProjectAngular\CodeProjectAngular
Open your favorite browser and go to :
http://localhost/angular/#/movies
As you might have noticed the Movies are hard coded inside the view. Next, we will remove the hardcoding from the View and put it inside the controller.
/App/controllers.js
angular.module('app.controllers', [])
.controller('MoviesController', function ($scope)
{
$scope.movies =
[
{ Id: 1, Name: "Fight Club",Director: "David Fincher" },
{ Id: 2, Name: "Into The Wild", Director: "Sean Penn" },
{ Id: 3, Name: "Dancer in the Dark", Director:"Lars von Trier " }
];
});
What’s with that $scope thingy?
Angular is more than MVC its MVVM as well. Anything that starts with ‘$’ is an internal Angular object. So $scope is an internal object, so you are wondering what does it do? Think of $scope as a public Static Class, there is one instance of it and if you change it in one place it will be changed in all the rest. Since the Controller reads/writes inside the $scope and the View reads/writes inside the same $scope then any change will be available for both.
As you noticed, there is a double binding between View<=>$scope and Controller <=> $scope. Thus, when $scope is updated, both the Controller and View are updated.
How to read $scope in the View
Inside the controller, we initialized $scope.movies as an array and populated it. Inside the View, we would like to loop the array and render the objects. Angular extends HTML and allows us to write loop functions inside HTML. When accessing the $scope inside the View, we omit the $scope. So to access $scope.movies inside the view we just say “movies”.
/Views/Movies.html
<div class="row">
<h2>Movies</h2>
</div>
<div class="row">
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Director</th>
</tr>
</thead>
<tbody>
<!-- foreach movie, a new tr will be created -->
<tr ng-repeat="movie in movies"> <!-- Similar to a foreach loop, C#: foreach(var movie in movies ){...} -->
<td>
{{movie.Id}}
</td>
<td>
{{movie.Name}}
</td>
<td>
{{movie.Director}}
</td>
</tr>
</tbody>
</table>
</div>
What did we just do?
We moved the hardcoded movies from the View to the Controller, and added an Angular looping function to loop over the array and display the data.
WebAPI to the rescue!
Because Angular runs on the client, it’s not capable of fetching data from the database. This is where WebAPI comes into play. So the next step is to fetch the Javascript Object from WebAPI (database).
Creating a WebAPI Project
- Right click on the solution
- Add
- New Project
- Choose WebAPI
- Change Authentication => No Authentication
- Name it "CodeProjectAngular.WebAPI"
Configure WebAPI to return JSON
Go to App_Start/WebApiConfig.cs and add the following code:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
The above code will not return a strict "application/json" response, if you want a strict "application/json" respond you can use the below.
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
config.Formatters.Remove(config.Formatters.XmlFormatter);
json.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
Creating the return type object
Create a folder named DTO (data transfer object) and create a new class called “MoviesDTO”, place the following code to /DTO/MoviesDTO.cs
public class MoviesDTO
{
public int Id { get; set; }
public string Name { get; set; }
public string Director { get; set; }
}
You will notice that the MoviesDTO has the same structure as the JavaScript Object we hard coded earlier. Thus, MoviesDTO has a property of Id, Name, and Director. When we return this Object it will be automatically Serialized to JSON. Next we will write the controller that returns this Object.
Adding the WebAPI Controller
- Right click on the Controller Folder
- Add => Controller
- Choose Web API 2 Controller – Empty
- Call it MoviesController
Now Paste the Below Code to /Controllers/MoviesController.cs
public IEnumerable<MoviesDTO> Get()
{
List<MoviesDTO> movies = new List<MoviesDTO>
{
new MoviesDTO { Id = 1, Name = "Fight Club", Director = "David Fincher" },
new MoviesDTO { Id = 2, Name = "Into The Wild", Director = "Sean Penn" },
new MoviesDTO { Id = 3, Name = "Dancer in the Dark", Director = "Lars von Trier" },
new MoviesDTO { Id = 4, Name = "WebAPI", Director = "Cool!" }
};
return movies;
}
Adding the WebAPI to the IIS
Press the Windows Key and search for “IIS” which stands for (Internet Information Service). If you don’t have it you might need to install it.
- Expand “Sites”
- Right click on “Default Web Site” => and choose “Add Application”
- In the Alias, enter “angular-webapi”
- Point the physical path to your WebAPI directory.
X:\ CodeProjectAngular\CodeProjectAngular.WebAPI
Testing your WebAPI
Open your favorite browser and enter the following URL:
http://localhost/angular-webapi/api/movies
Putting it all together!
All we have to do now is to call this WebAPI from Angular. Note that we injected “$http” to the controller and we will be using that to call the WebAPI.
/App/controllers.js
angular.module('app.controllers', [])
.controller('MoviesController', function ($scope, $http)
{
$http({
method: 'GET',
url: 'http://localhost/angular-webapi/api/movies'
})
.success(function (data)
{
$scope.movies = data;
});
});
Voilà! We are done!