As web technologies continue to evolve, developers have to learn new technologies so that they can build successful web-based applications that stand above the crowd. This can be a challenging proposition, especially for developers moving from desktop or Rich Internet Application (RIA) development frameworks. To help developers learn the latest HTML5, Cascading Style Sheets Level 3 (CSS3), and JavaScript technologies, several developer colleagues and I built a sample application for demonstration at Microsoft's MIX 11 conference. The application, called Account at a Glance, takes advantage of key web technologies and uses them to display brokerage account information to consumers. (See the end of this article for the code-download URL.)

The application was built in Q1 2011 by Dan Wahlin (client-side and server-side coding); Corey Schuman (design and client-side coding); Jarod Ferguson (client-side coding); and John Papa (Entity Framework Code First coding). John Papa, Giorgio Sardo, and Scott Guthrie also provided feedback and offered several key suggestions and ideas that were incorporated into the application. Figure 1a shows the Account at a Glance application as it was first conceived on a whiteboard, and Figure 1b shows how it ended up after the project was completed.

Figure 1A: The Account at a Glance application as originally conceived

Figure 1B: The Account at a Glance application screen—final version

We built the Account at a Glance application to demonstrate how cutting-edge web technologies can be used together to build a dynamic application capable of displaying account information, video news, quotes and charts, market news, and more without the use of plug-ins. The app loads data dynamically, using AJAX technologies, into tiles that are displayed within the application. As tiles are dragged and dropped to different locations in the interface, data is re-rendered, depending upon the size of the tile that is targeted, as shown in Figures 2a and 2b (small, medium, and large tile sizes exist). This allows data to be displayed in several different ways and provides a means for customers to customize how account information is displayed by moving tiles around.

Figure 2A: Dragging a tile to a different area of the screen

Figure 2B: Automatic resizing of tiles on screen, via jQuery templates

The Account at a Glance application uses these technologies:

This article provides an overview of the Account at a Glance application. Part 2 will provide details about the client-side technologies used, including HTML5 features such as jQuery templates, SVG, Canvas, and video.

The Account at a Glance Solution

The Account at a Glance application is comprised of a single solution with two projects. The first project is named AccountAtAGlance and uses the ASP.NET MVC 3 project template. The second project is named AccountAtAGlance.Model and is a Class Library project. Figure 3 shows the solution and project structure.

Figure 3: The Account at a Glance solution

The AccountAtAGlance project follows the standard ASP.NET MVC 3 folder structure. The Controllers folder contains the controller classes used in the application; the views are located in the Views folder. The Account at a Glance application relies heavily on client-side technologies such as jQuery, and the scripts used in the application can be found in the Scripts folder. Several jQuery plug-ins were used to create the application: jQuery UI, Flot (Canvas rendering), Raphael (SVG rendering), and DataTables. JSON data is exchanged between the client browser and server using ASP.NET MVC actions and rendered using jQuery Templates that are dynamically loaded from the server. CSS is used heavily throughout the application. The .css files are located in the Content folder.

The AccountAtAGlance.Model project contains the application's data-access functionality. The project contains the Code First classes that define the structure of model classes used throughout the application and also a DbContext class named AccountAtAGlance.cs. The Repository folder contains data-access classes that perform Create, Read, Update, and Delete (CRUD) operations on behalf of the application. LINQ technologies are used in the application to simplify the data-access code and provide filtering and sorting functionality. The application makes RESTful service calls to ASP.NET MVC 3 actions that expose data and objects defined in the AccountAtAGlance.Model project. It also calls out to a Google financial service to retrieve stock quotes and simulates random market index quotes on a timed basis.

The next sections provide details on the data-access technologies and web framework used in the application.

Code First and the Repository Pattern

When we started building the Account at a Glance application, we used Entity Framework 4.0's Model First option. However, Entity Framework Code First was about to be released, so we converted to that technology in the middle of the project (thanks to Scott Guthrie for the suggestion to go with Code First and John Papa for doing the conversion from Model First). If you're new to Code First, Entity Framework 4.1 provides a Code First approach that shifts the focus to working with Plain Old CLR Objects (POCO), which keeps your data model classes nice and clean. To use Code First, install NuGet, then go to View, Other Windows, Package Manager Console and type the following command at the prompt, as shown in Figure 4:

  1. Install-Package EntityFramework
Figure 4: Using the NuGet Package Manager Console to install Entity Framework 4.1 and Code First

POCOs are used to define entities used in the application. Figure 5 shows an example of the BrokerageAccount POCO class, which defines several different properties as well as three navigation properties.

  1. namespace AccountAtAGlance.Model
  2. {
  3.     public class BrokerageAccount
  4.     {
  5.         public BrokerageAccount()
  6.         {
  7.             Positions = new HashSet<Position>();
  8.             Orders = new HashSet<Order>();
  9.         }
  11.         // Primitive properties
  12.         public int Id { get; set; }
  13.         public string AccountNumber { get; set; }
  14.         public string AccountTitle { get; set; }
  15.         public decimal Total { get; set; }
  16.         public decimal MarginBalance { get; set; }
  17.         public bool IsRetirement { get; set; }
  18.         public int CustomerId { get; set; }
  19.         public decimal CashTotal { get; set; }
  20.         public decimal PositionsTotal { get; set; }
  21.         public int WatchListId { get; set; }
  23.         // Navigation properties
  24.         public ICollection<Position> Positions { get; set; }
  25.         public ICollection<Order> Orders { get; set; }
  26.         public WatchList WatchList { get; set; }

POCO classes defined in the application are used to automatically generate the database that the application uses. A class named AccountAtAGlance that derives from DbContext is used to query the database, as shown in Figure 6. This class is located in the AccountAtAGlance.Model project's Repository folder.

  1. using System.Data.Entity;
  3. namespace AccountAtAGlance.Model.Repository
  4. {
  5.     public class AccountAtAGlance : DbContext
  6.     {
  7.         public AccountAtAGlance() : base("name=AccountAtAGlance") { }
  9.         public DbSet<BrokerageAccount> BrokerageAccounts { get; set; }
  10.         public DbSet<Customer> Customers { get; set; }
  11.         public DbSet<Exchange> Exchanges { get; set; }
  12.         public DbSet<MarketIndex> MarketIndexes { get; set; }
  13.         public DbSet<Order> Orders { get; set; }
  14.         public DbSet<OrderType> OrderTypes { get; set; }
  15.         public DbSet<Position> Positions { get; set; }
  16.         public DbSet<Security> Securities { get; set; }
  17.         public DbSet<MutualFund> MutualFunds { get; set; }
  18.         public DbSet<Stock> Stocks { get; set; }
  19.         public DbSet<WatchList> WatchLists { get; set; }
  21.         public int DeleteAccounts()
  22.         {
  23.             //return base.Database.SqlCommand("DeleteAccounts");
  24.             return base.Database.ExecuteSqlCommand("DeleteAccounts");
  25.         }
  27.         public int DeleteSecuritiesAndExchanges()
  28.         {
  29.             return base.Database.
  30.              ExecuteSqlCommand("DeleteSecuritiesAndExchanges");
  31.         }
  33.         protected override void OnModelCreating(DbModelBuilder modelBuilder)
  34.         {
  35.             // base.OnModelCreating(modelBuilder);          
  36.             // inherited table types
  37.             // Map these class names to the table names in the DB
  38.             modelBuilder.Entity<Security>().ToTable("Securities");
  39.             modelBuilder.Entity<Stock>().ToTable("Securities_Stock");
  40.             modelBuilder.Entity<MutualFund>().ToTable("Securities_MutualFund");
  42.             // Many to many resolver
  43.             // Map the WatchList and Securities navigation property using
  44.             // the WatchListSecurity Many-to-Many table.
  45.             // To avoid a Cycle condition, WatchList has Securities,
  46.             // but Security does not have WatchLists.
  47.             modelBuilder.Entity<WatchList>().HasMany(w =>
  48.                w.Securities).WithMany()
  49.                     .Map(map => map.ToTable("WatchListSecurity")
  50.                     .MapRightKey("SecurityId")
  51.                     .MapLeftKey("WatchListId"));
  52.         }
  53.     }
  54. }

The AccountAtAGlance class relies on the new fluent API to map some POCO classes to database tables, such as mapping Security to Securities and Stock to Securities_Stock. This is accomplished by overriding the OnModelCreating() method and defining the necessary mappings.

Classes that follow the Repository Pattern are located in the Repository folder of the AccountAtAGlance.Model project. Several different classes are provided to handle various query functionality. Figure 7 shows a section of the AccountRepository class that handles querying customer account information. It uses the AccountAtAGlance DbContext class to perform the query.

  1. namespace AccountAtAGlance.Model.Repository
  2. {
  3.     public class AccountRepository : RepositoryBase<AccountAtAGlance>,
  4.       IAccountRepository
  5.     {
  6.         public Customer GetCustomer(string custId)
  7.         {
  8.             using (var context = DataContext)
  9.             {
  10.                 return context.Customers
  11.                     .Include("BrokerageAccounts")
  12.                     .Where(c => c.CustomerCode == custId).SingleOrDefault();
  13.             }
  14.         }
  15.     }
  16. }

JSON and MVC Actions

I'm a big fan of ASP.NET MVC because it provides complete control over the HTML returned from the server, provides a solid architecture and well-defined conventions, and allows JSON objects to be returned from the server easily with minimal code (to name just a few of MVC's great features). Most of the Account at a Glance application's functionality occurs on the client side with JavaScript, but the application still needs to get data from the server. We initially planned on using Windows Communication Foundation (WCF) REST features to serve up JSON, but because we were using ASP.NET MVC as the application framework, we decided to use controller actions instead.

Using controller actions provides a simple way to return custom JSON objects back to the client where they can be manipulated using jQuery templates. jQuery APIs such as getJSON() are used to call the ASP.NET MVC actions. (I'll provide additional details in the next article.) Figure 8 shows an example of actions that return account details and security quotes.

  1. public ActionResult GetAccount(string acctNumber)
  2. {
  3.     return  Json(_AccountRepository.GetAccount(acctNumber),
  4.        JsonRequestBehavior.AllowGet);
  5. }
  7. public ActionResult GetQuote(string symbol)
  8. {
  9.     return  Json(_SecurityRepository.GetSecurity(symbol),
  10.        JsonRequestBehavior.AllowGet);
  11. }

Each action calls into the appropriate repository class, which handles retrieval of data from the database. Once the data is retrieved and mapped to model objects, the objects are serialized to JSON using the built-in Json() method in ASP.NET MVC controllers and passed back to the client for processing.

An Integrated Approach

The Account at a Glance application provides a robust example of how different technologies can integrate together from server side to client side. In this first article you've seen how the application solution is structured and the different technologies that were used on the server side, including Entity Framework Code First and ASP.NET MVC. In "How to Build a jQuery HTML5 Web Application with Client-Side Coding," I'll provide more details about the client-side coding and scripts that were used, including patterns that the team used to structure JavaScript code. You can download the application code at the URL below if you'd like to explore it in more detail.

Download the Account at a Glance application.