Single Page Application (SPA) using AngularJS and WebAPI – Architecture

The goal of this post is to clarify an architecture of a single page application using the following technologies:

  • ASP MVC
  • AngularJS
  • WebAPI
  • Entity Framework

The next diagram shows at the left the client side and at the right the server side:

Single Page Application (SPA) using AngularJS and WebAPI – Architecture

 

 The first row is the communication between the different used technologies.

The middle row represent the logic of our application and the last the data containers used on these classes.

Using the previous diagram is easy to see which data each layer uses.

e.g:

  1. The Angular controller can only work with the Angular context.
  2. The WebAPI controller send and receive data in JSON format. The JSON objects are automatically translated to C# view models. The WebAPI controllers are also able to map the view-models to domain objects to use the domain services. WebAPI controllers can also request domain objects to the domain services and translate it to ViewModels c# before sending it back to the client-side in JSON format.

Data containers and layers:

  • AngularJS Context: The context is populated by the angular repository. HTML templates bind to it.
  • ViewModels Json: The data is sent from client to server side and vice versa in JSON format. The WebAPI controller send automatically by default the data in this format. The send and received data in JSON format is mapped automatically to the expected object.
  • ViewModels C#: The data the WebAPI controller send and receive as parameter. The conversion between Json and C# view models is done automatically by the WebAPI controller. This class is a subset of our entity domain objects plus some calculated properties that our views may need. It can be used for example to keep some server-side data hidden on the client-side.
  • Entities: Entity Framework entities or domain specific classes. All the data related to the domain. Theses classes are completely independent of the view. The domain services or application logic must use theses classes. The mapping from and to Entities to c# view models can be done automatically or Auto-mapper.

AngularJS AJAX calls

AngularJS is a JavaScript framework that allows us to create Single Page Applications (SPA). If we use AngularJS we can bind from our HTML views to JavaScript files (controllers). Controllers will offer the data to the view. Typically this data is retrieved from REST services using Ajax calls.

The goal of this post is to show how to make AJAX calls using AngularJS. I will illustrate two different ways to do it, the first one helps to understand how the asynchronous call works, the second one is an easier way to do it using a higher-level service.

Using $http and $q

One way to make AJAX calls using AngularJS is using the services $http and $q:

  • The $http service allows us to make the GET and POST calls.
  • The $q service is used to wait asynchronously for the response, basically it is a deferred result, it returns a “promise” that will response after some time. After some time the deferred can be “resolved” or “rejected”.   The method using this deferred can add two call-backs to it one to execute when it is resolved and one when it is rejected.

Let say we have a controller that needs to populate some data asynchronously. I like to dedicate the controller to define the binds for our views. The AJAX call will be executed in a different file, a repository.

AngularJS – Controller: The module will call a repository and add set the response in the scope when the deferred is resolved.

angular js controller

AngularJS – Repository: The repository make an AJAX Get request to a ASP.NET WebAPI Controller.

angular js repository

We can write the same repository with less lines using shortcut methods:

angular js repository

This solution works but there is an easier way to do AJAX calls…

Using $resource

This service lets us interact with RESTful server-side data sources with a higher-level than the $http service. The $resource service is defined in the module ‘ngResource’ and this module is in the file angular-resource.js.

The first thing that we need to do is to reference the angular-resource.js file and add this module as a dependency of our module:

ngResource reference

ngResource reference

Using the $resource we can write our controller and repository easier because we don’t have to deal directly with deferred objects.

This is now the implementation of our controller and repository using the Angular service $resource , really easy!

angular js repository and controller

ASP MVC – Template Overview

When a new MVC Web Application is created in Visual Studio a lot of files are added to the solution. The goal of this post is to provide a small overview of all these files, this overview should make easier to understand the MVC solution structure.

The files described here are the files created by default when you add a web project using the MVC template.

Create a a Web project:

New Web Project

Use the MVC Template:

MVC Template

This is the generated project:

MVC Template Project

ASP MVC Template Overview

Let’s start enumerating some created folders:

  • Content: CSS files with view styles. (Bootstrap)
  • Fonts: Some fonts required by the CSS files.
  • Scripts: JavaScript files. (JQuery)
  • Controllers: C# files with the code that is going to be run at the server side.

Now the rest of files and folders with some more details:

Views

This folder contains *.cshtml files. The Razor engine generates the views of our web application out of these files. Typically we will have a view or a group of views for each controller. This folder also contains a Web.config don’t confuse this one with the Web.config at the root of the solution. Razor engine is configured here.

Continue reading

Entity Framework – Lazy Loading

I want to analyse in this post how Entity Framework really interact with the database. i.e. The queries that are really executed.

In previous post I created a database using Code First. These are two of my entities:

A food representation:

public class Food
{
    /// <summary>
    /// Gets or sets the food identifier.
    /// </summary>
    [Key]
    // NOTE: As the name is className + id, this property is not needed
    public int Id { getset; }
 
    /// <summary>
    /// Gets or sets the food name.
    /// </summary>
    [MaxLength(200)]
    [Index(IsUnique = true)]
    public string Name { getset; }
 
    /// <summary>
    /// Gets or sets the recipes needing this Food
    /// </summary>
    // NOTE: EF needs the virtual attribute to enable Lazy loading 
    public virtual List<Recipe> RecpiesNeedingThisFood { getset; }
 
    /// <summary>
    /// Returns a <see cref="System.String" /> that represents this instance.
    /// </summary>
    public override string ToString()
    {
        return string.Format("{0} ({1})"this.Name, this.Id);
    }
}

An entry on my fridge representation: a food and an expire date of this food.

public class FridgeEntry
{
    /// <summary>
    /// Initializes a new instance of the <see cref="FridgeEntry"/> class.
    /// </summary>
    public FridgeEntry()
    {
        ExpireDate = DateTime.MaxValue;
    }
 
    public int Id { getset; }
 
    [Required]
    // NOTE virtual is needed for lazy loading
    public virtual Food Food { getset; }
 
    /// <summary>
    /// Gets or sets the expire date.
    /// </summary>
    public DateTime ExpireDate { getset; }
 
 
    /// <summary>
    /// Returns a <see cref="System.String" /> that represents this instance.
    /// </summary>
    public override string ToString()
    {
        return string.Format("FoodId ({0}) - expire date: {1}"this.Id, this.ExpireDate);
    }
}

How to debug the queries and connections between EF and my database?

A new feature of EF6 is the possibility to log everything that Entity Framework is doing.

The context.Database has a Log property which is type Action<string> if this action is not null EF will call it always he connect to the database.

Define a logger, to analyse the Lazy loading a simple method writing in console the messages is enough:

private static void ConsoleLogger(string msg)
{
    msg = msg.Trim();
 
    if (!string.IsNullOrEmpty(msg))
    {
        Console.ForegroundColor = ConsoleColor.DarkGray;
        Console.WriteLine(DateTime.Now.TimeOfDay.ToString("g"));
        Console.ForegroundColor = ConsoleColor.DarkGreen;
        Console.WriteLine(msg);
 
        Console.ResetColor();
    }
}

Now we just have to define this  logger as the logger of the context.Database.

EF Lazy loading testing

We have already a way to see the connections between EF and the database, now let’s analyse it:

Continue reading

Entity Framework – Local and Azure connection

In previous posts I used EF using the local database and using the Azure SQL Server. This is the configuration I use now to connect to my local database in Debug mode and to my Windows Azure database in Release Mode.

App.config

  <connectionStrings>
    <!--Azure MyFood database-->
    <add 
        name="MyFoodAzure"
        providerName="System.Data.SqlClient"
        connectionString="Data Source=i608rt1tak.database.windows.net;Initial Catalog=MyFood;Integrated Security=False;User ID=ravened;Password=pass¿;Connect Timeout=60;Encrypt=False;TrustServerCertificate=False" />
    
    <!--Local MyFood database-->
    <add 
        name="MyFoodLocal"
        providerName="System.Data.SqlClient"
        connectionString="Server=(localdb)\v11.0;Integrated Security=true;Database=MyFood;"/>
  </connectionStrings>

DbContext

    public class FoodContext : DbContext
    {
 
        // NOTE: Call base constructor to specify the connection string name
#if !DEBUG
        // In Release mode it will look for the Cloud connection string
        public FoodContext() : base("name=MyFoodAzure") { }
#else
        // In Release mode it will look for the Cloud connection string
        public FoodContext() : base("name=MyFoodLocal") { }
#endif
 
        public DbSet<Food> Foods { getset; }
        public DbSet<Recipe> Recipes { getset; }
        public DbSet<FridgeEntry> Fridge { getset; }
 
    }