Remember your Hot Towel when going to the SPA! (ASP.NET MVC 4)

Posted by: Fanie Reynders , on 6/30/2013, in Category ASP.NET MVC
Views: 48106
Abstract: Poke around in Hot Towel - a Single Page Application template in ASP.NET MVC 4 to kick start your next project for the modern web

Ultimately, the goal of any app is to give the user the best experience possible. The way some old-fashioned websites work, causes disruption in this user experience flow. Performing a simple task with traditional web apps causes the entire page to post-back to the server, have a cup of coffee and return back to the client with (hopefully) a different screen.

Single Page Applications (SPAs) are one of the latest trends in web technology today. It allows us to have the fluid user experience of a desktop app together with the scalability of a web app.

This article is published from the DNC .NET Magazine – A Free High Quality Digital Magazine for .NET professionals published once every two months. Subscribe to this eMagazine for Free


Getting started

Bundled with the ASP.NET and Web Tools 2012.2 Update, is a new SPA template that allows developers to build rich interactive client-side web apps using HTML5, CSS3 and some JavaScript libraries. The ASP.NET team provided one template and the Community jumped in with five more!

One of the community driven templates you can use is Hot Towel. It was built by John Papa. It comes power-packed with everything you need out of the box and provides you with modular code structure, powerful data management and easy elegant styling. The template gives you everything you need to get started with SPA so you can focus on your app and not the “other stuff”. Download the VSIX here: http://bit.ly/151Mk9o (direct download).

Pre-requisites

  • Visual Studio 2012 or Visual Studio Express 2012 for Web
  • ASP.NET Web Tools 2012.2 update

Let’s do this, shall we?

In Microsoft Visual Studio 2012, select ‘File’ > ‘New’ > ‘Project…’ and then pick the ‘ASP.NET MVC 4 Web Application’ template from the Web section.

new-project-dialog

Name the project something interesting and click ‘OK’. You will be presented with the following New MVC 4 Project dialog:

hot-towel-template

The dialog above may be familiar for those of you that are well versed in ASP.NET MVC, but after installing the ASP.NET Web Tools 2012.2 update, you will notice a new template has been added to the list: ‘HotTowel Single Page Application’. Pick it and click ‘OK’.

The SPA HotTowel template is also available on NuGet:

install-from-nuget

You can find out more by heading here: http://nuget.org/packages/HotTowel/

Poking around the structure

After Visual Studio did its thing, you will notice that the project has a similar structure as that of the good old stock standard ASP.NET MVC 4 project.

clip_image002

This includes:

  • App_Start – Start-up server side logic
  • Content – Usually contains images and css
  • Controllers – Page & API Controllers
  • Models – Model & View Model classes
  • Scripts – JavaScript files
  • Views – All the pages for the application

In addition, we notice that HotTowel SPA provides an ‘App’ folder which contains a collection of modules that encapsulates functionality and declare dependencies on other modules. Here is where all the magic happens. Your entire application basically lives in this domain.

app-layout

Durandal is a cross-device, cross-platform client framework and designed to make SPAs easy to create.

The presentation logic for the views resides in the ‘viewmodels’ folder. This is a common MVVM pattern.

In the ‘views’ folder, you will see pure HTML files for your application. This is mainly driven by templating functionality of Knockout (a JavaScript library for MVVM).

View by feature

The SPA HotTowel template comes power-packed with the following functionality:

  • ASP.NET MVC
  • ASP.NET Web API
  • ASP.NET Web Optimization for bundling and minification
  • Breeze.js for rich data management
  • Durandal.js for view composition, app life cycle and navigation
  • Knockout.js for data bindings
  • Require.js for modularity
  • Toastr.js for notifications (pop-up messages)
  • Twitter Bootstrap for styling

4 Easy steps to get building on HotTowel

1. Add your custom server-side code (preferably ASP.NET Web API and/or Entity Framework)

2. Create your viewmodels in the ‘App/viewmodels’ folder

3. Create your screens (views) using HTML in the ‘App/views’ folder and implement the Knockout data bindings in your views

4. Update the navigation routes in ‘shell.js’

Walkthrough

Index.csthml

Looking in the ‘Views/HotTowel’ folder, we find a view called ‘Index.cshtml’ that serves as the starting point for the MVC application. In a SPA (as the name implies), we are only using one page to host a collection of views for our application.

The ‘Index.cshtml’ view contains all the meta-tags, style sheet- and JavaScript references you would expect. Let’s examine the ‘body’ tag:


@Html.Partial("_splash")

   
@Scripts.Render("~/scripts/vendor")


The ‘applicationHost’ div is the host for the HTML views. Next it renders the ‘vendor’ bundle that contains all the external vendor JavaScript references.

The entrance point for the application’s code specified by referencing Require.js and assigning the ‘main’ data-attribute where to find the start-up JavaScript logic.

Main.js

This the start-up code for your application and contains the navigation routes, the start-up view definition and any bootstrap logic you may want to implement when the application initially fires up.

Several of Durandal’s modules are defined in Main.js to help kick start the process, the ‘define’ statement helps resolve module dependencies so they are available within the context.

define(['durandal/app', 'durandal/viewLocator', 'durandal/system', 'durandal/plugins/router', 'services/logger'],
function (app, viewLocator, system, router, logger) {
  // Enable debug message to show in the console
  system.debug(true);
  app.start().then(function () {
   toastr.options.positionClass = 'toast-bottom-right';
   toastr.options.backgroundpositionClass = 'toast-bottom-right';
   router.handleInvalidRoute = function (route, params) {
    logger.logError('No Route Found', route, 'main', true);
   };
 
   // When finding a viewmodel module, replace the viewmodel string
   // with view to find it partner view.
   router.useConvention();
   viewLocator.useConvention();
   // Adapt to touch devices
   app.adaptToDevice();
   //Show the app by setting the root view model for our application.
   app.setRoot('viewmodels/shell', 'entrance');
  });
});

Views

All the views are found in the ‘App/views’ folder and only contains pure HTML files. The ‘shell.html’ contains the master layout of our application (similar to the ‘_Layout.cshtml’) and all of the other views will be composed somewhere inside this.

3 regions are used in the layout view: A header, content area (section) and footer. Each of these regions will be loaded with content from other views when requested.



 


 
 


 


In ‘nav.html’ is an example of how Knockout.js is leveraged for rich model binding:


ViewModels

The application’s viewmodels are found in the ‘App/viewmodels’ folder. Inside the ‘shell.js’, ‘home.js’ and ‘details.js’ contain properties and functions bound to ‘shell.html’, ‘home.html’ and ‘details.html’ respectively. For example, let’s explore ‘home.html’:




And ‘home.js’:

define(['services/logger'], function (logger) {
var vm = {
  activate: activate,
  title: 'Home View'
};
return vm;
 
function activate() {
  logger.log('Home View Activated', null, 'home', true);
  return true;
}
});

Services

All the application specific services are found in the ‘App/services’ folder. HotTowel comes standard with the ‘logger.js’ service responsible for logging messages and also displaying it on the screen as toast notifications. In the ‘services’ folder is the ideal place to put logic like data-retrieval for instance.

Running the template

Out of the box, HotTowel is ready to run. Just hit F5 and you’ll get:

default-app

Hands on example

Let’s say you want to create a page called ‘Tweets’ that shows the latest tweets from DotNetCurry.

Implement the service

We will need some kind of service that will be responsible for retrieving tweets from Twitter given a certain search term. Right-click the ‘App/services’ folder and add a new JavaScript file called ‘twitter.js’ with the following contents:

define(function () {
  var tweetModel = function (user, image, tweet) {
   this.user = user;
   this.tweet = tweet;
   this.image = image;
  };
  var model = {
   loadTweets: load,
  };
  return model;
 
  function load(query, list) {
   return $.ajax({
    url: "
http://search.twitter.com/search.json?q=" + query,
    crossDomain: true,
    dataType: "jsonp"
   }).done(function (data) {
    $.each(data.results, function (i, d) {
    list.push(new tweetModel(d.from_user, d.profile_image_url, d.text));
   });
  });
}
});

The service exposes a function called ‘loadTweets’ that expects a query and a list object. Given the parameters, it will asynchronously load tweets with the given search query and populate the list object which must be observable by Knockout.

Create the ViewModel

Now we need to consume our Twitter service. Right-click the ‘App/viewmodels’ folder and add a new JavaScript called ‘tweets.js’ with the following contents:

define(['services/logger', 'services/twitter'], function (logger, twitter) {
var vm = {
  activate: activate,
  title: 'Tweet results for "DotNetCurry"',
  tweets: ko.observableArray([])
};
return vm;
 
function activate() {
  twitter.loadTweets("dotnetcurry", vm.tweets);
  logger.log('Tweet page activated', null, 'tweets', true);
  return true;
}
});

Notice how we resolve dependencies using the ‘define’ function. In this case, I need to use the logger service and our twitter service situated in ‘services/logger’ and ‘services/twitter’ respectively.  One of the properties the model comprises of is ‘tweets’. Notice that it is an observable array, which means Knockout will be handling the real-time change tracking.

On the model activation, we use the Twitter service to load tweets with query “dotnetcurry” as well as passing in the observed tweet list object (from our model).

Create the View

Now for the Tweet page, right click the ‘App/views’ folder and add a HTML page with the name ‘tweets.html’ containing the following HTML:




     

  •   

       
       

        
        
       

      

     



For each tweet in the model, it will create a list item tag containing an image of the user including his/her name as well as the tweet that was posted.

*Note that I am using Bootstrap’s styling to accomplish the nice effects as well as my own custom styles.

Wire up the navigation

The last thing we must do is to tell the shell about the new page. In the ‘App/viewmodels/shell.js’ file add the map of the tweet page on the boot function:

function boot() {
router.mapNav('home');
router.mapNav('details');
router.mapNav('tweets');
log('Hot Towel SPA Loaded!', null, true);
return router.activate('home');
}

Let it run!

After hitting F5, you’ll notice a new menu item ‘tweets’. After clicking it, we are presented with the tweet page that we just created:

sample-app-twitter

Conclusion

The power of SPAs are great and endless and the new HotTowel SPA template is a great way to get started. As application developers, we don’t want to worry about the boring plumbing but be able to quickly start working with the fun stuff, this template allows us to do just that.

HotTowel really makes it easy to create fast, durable, modular, cross-browser and sexy Single Page Applications with rich navigation and data access functionality. This is definitely on the tech-stack for my next web app.

Download the entire source code from Github here http://bit.ly/dncm6-ht

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Fanie Reynders is a Microsoft Certified Professional from South Africa. Being a web technology evangelist in his own right, he has been developing on the Microsoft stack for over 9 years. Follow him on Twitter @FanieReynders and read his blog


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by sampath on Tuesday, August 13, 2013 10:46 AM
Yup,Clean and clear explanation about the awesome framework.Keep up the good work.
Comment posted by frank on Friday, September 13, 2013 9:42 PM
tweets page only display Tweet results for "DotNetCurry "
but no twitter linked page show. I just copy all the code.
think something wrong with twitter.js ajax call
url: "http://search.twitter.com/search.json?q=" + query,
or something not explained in article.
Comment posted by Sean on Friday, September 20, 2013 10:28 AM
@frank - The version 1.0 twitter API is now depreciated, and the request will need to be updated to work with version 1.1

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

Tags

JQUERY COOKBOOK

jQuery CookBook