Building an HTML5 App with ASP.NET

I’m teaching several JavaScript and ASP.NET workshops over the next couple of months (thanks everyone!) and I thought it would be useful for my students to have a really easy to use JavaScript reference. I wanted a simple interactive JavaScript reference and I could not find one so I decided to put together one of my own.

I decided to use the latest features of JavaScript, HTML5 and jQuery such as local storage, offline manifests, and jQuery templates. What could be more appropriate than building a JavaScript Reference with JavaScript?

You can try out the application by visiting:

http://samples.Superexpert.com/JavaScriptReference

Because the app takes advantage of several advanced features of HTML5, it won’t work with Internet Explorer 6 (but really, you should stop using that browser). I have tested it with IE 8, Chrome 8, Firefox 3.6, and Safari 5.

You can download the source for the JavaScript Reference application at the end of this article.

Superexpert JavaScript Reference

Let me provide you with a brief walkthrough of the app. When you first open the application, you see the following lookup screen:

clip_image002

As you type the name of something from the JavaScript language, matching results are displayed:

clip_image004

You can click the details link for any entry to view details for an entry in a modal dialog:

clip_image006

Alternatively, you can click on any of the tabs — Objects, Functions, Properties, Statements, Operators, Comments, or Directives — to filter results by type of syntax. For example, you might want to see a list of all JavaScript built-in objects:

clip_image008

You can login to the application to make modification to the application:

clip_image010

After you login, you can add, update, or delete entries in the reference database:

clip_image012

HTML5 Local Storage

The application takes advantage of HTML5 local storage to store all of the reference entries on the local browser. IE 8, Chrome 8, Firefox 3.6, and Safari 5 all support local storage.

When you open the application for the first time, all of the reference entries are transferred to the browser. The data is stored persistently. Even if you shutdown your computer and return to the application many days later, the data does not need to be transferred again.

Whenever you open the application, the app checks with the server to see if any of the entries have been updated on the server. If there have been updates, then only the updates are transferred to the browser and the updates are merged with the existing entries in local storage. After the reference database has been transferred to your browser once, only changes are transferred in the future.

You get two benefits from using local storage. First, the application loads very fast and works very fast after the data has been loaded once. The application does not query the server whenever you filter or view entries. All of the data is persisted in the browser.

Second, you can browse the JavaScript reference even when you are not connected to the Internet (when you are on the proverbial airplane). The JavaScript Reference works as an offline application for browsers that support offline applications (unfortunately, not IE).

When using Google Chrome, you can easily view the contents of local storage by selecting Tools, Developer Tools (CTRL-SHIFT I) and selecting Storage, Local Storage:

clip_image014

The JavaScript Reference app stores two items in local storage: entriesLastUpdated and entries.

HTML5 Offline App

For browsers that support HTML5 offline applications – Chrome 8 and Firefox 3.6 but not Internet Explorer – you do not need to be connected to the Internet to use the JavaScript Reference. The JavaScript Reference can execute entirely on your machine just like any other desktop application.

When you first open the application with Firefox, you are presented with the following warning:

clip_image016

Notice the notification bar that asks whether you want to accept offline content. If you click the Allow button then all of the files (generated ASPX, images, CSS, JavaScript) needed for the JavaScript Reference will be stored on your local computer.

Automatic Script Minification and Combination

All of the custom JavaScript files are combined and minified automatically whenever the application is built with Visual Studio. All of the custom scripts are contained in a folder named App_Scripts:

clip_image017

When you perform a build, the combine.js and combine.debug.js files are generated. The Combine.config file contains the list of files that should be combined (importantly, it specifies the order in which the files should be combined). Here’s the contents of the Combine.config file:

 

<?xml version="1.0"?>
<combine>
    <scripts>
        <file path="compat.js" />
        <file path="storage.js" />
        <file path="serverData.js" />
        <file path="entriesHelper.js" />
        <file path="authentication.js" />
        <file path="default.js" />
    </scripts>
</combine>

 

jQuery and jQuery UI

The JavaScript Reference application takes heavy advantage of jQuery and jQuery UI. In particular, the application uses jQuery templates to format and display the reference entries.

Each of the separate templates is stored in a separate ASP.NET user control in a folder named Templates:

clip_image018

The contents of the user controls (and therefore the templates) are combined in the default.aspx page:

<!-- Templates -->

<user:EntryTemplate runat="server" />

<user:EntryDetailsTemplate runat="server" />

<user:BrowsersTemplate runat="server" />

<user:EditEntryTemplate runat="server" />

<user:EntryDetailsCloudTemplate runat="server" />

When the default.aspx page is requested, all of the templates are retrieved in a single page.

WCF Data Services

The JavaScript Reference application uses WCF Data Services to retrieve and modify database data. The application exposes a server-side WCF Data Service named EntryService.svc that supports querying, adding, updating, and deleting entries.

jQuery Ajax calls are made against the WCF Data Service to perform the database operations from the browser. The OData protocol makes this easy.

Authentication is handled on the server with a ChangeInterceptor. Only authenticated users are allowed to update the JavaScript Reference entry database.

JavaScript Unit Tests

In order to build the JavaScript Reference application, I depended on JavaScript unit tests. I needed the unit tests, in particular, to write the JavaScript merge functions which merge entry change sets from the server with existing entries in browser local storage.

clip_image019

In order for unit tests to be useful, they need to run fast. I ran my unit tests after each build. For this reason, I did not want to run the unit tests within the context of a browser. Instead, I ran the unit tests using server-side JavaScript (the Microsoft Script Control).

The source code that you can download at the end of this blog entry includes a project named JavaScriptReference.UnitTests that contains all of the JavaScripts unit tests.

JavaScript Integration Tests

Because not every feature of an application can be tested by unit tests, the JavaScript Reference application also includes integration tests.

I wrote the integration tests using Selenium RC in combination with ASP.NET Unit Tests. The Selenium tests run against all of the target browsers for the JavaScript Reference application: IE 8, Chrome 8, Firefox 3.6, and Safari 5.

For example, here is the Selenium test that checks whether authenticating with a valid user name and password correctly switches the application to Admin Mode:

[TestMethod]
    [HostType("ASP.NET")]
    [UrlToTest("http://localhost:26303/JavaScriptReference")]
    [AspNetDevelopmentServerHost(@"C:UsersStephenDocumentsReposJavaScriptReferenceJavaScriptReferenceJavaScriptReference", "/JavaScriptReference")]
    public void TestValidLogin() {
        // Run test for each controller
        foreach (var controller in this.Controllers) {
            var selenium = controller.Value;
            var browserName = controller.Key;

            // Open reference page.
            selenium.Open("http://localhost:26303/JavaScriptReference/default.aspx");

            // Click login button displays login form
            selenium.Click("btnLogin");
            Assert.IsTrue(selenium.IsVisible("loginForm"), "Login form appears after clicking btnLogin");

            // Enter user name and password
            selenium.Type("userName", "Admin");
            selenium.Type("password", "secret");
            selenium.Click("btnDoLogin");

            // Should set adminMode == true
            selenium.WaitForCondition("selenium.browserbot.getCurrentWindow().adminMode==true", "30000");
        }
    }

 

The results for running the Selenium tests appear in the Test Results window just like the unit tests:

clip_image020

The Selenium tests take much longer to execute than the unit tests. However, they provide test coverage for actual browsers. Furthermore, if you are using Visual Studio ALM, you can run the tests automatically every night as part of your standard nightly build.

You can view the Selenium tests by opening the JavaScriptReference.QATests project.

Summary

I plan to write more detailed blog entries about this application over the next week. I want to discuss each of the features – HTML5 local storage, HTML5 offline apps, jQuery templates, automatic script combining and minification, JavaScript unit tests, Selenium tests — in more detail.

You can download the source control for the JavaScript Reference Application by clicking the following link:

Download

You also can download the code from GitHub:

GitHub.com/StephenWalther

You need Visual Studio 2010 and ASP.NET 4 to build the application. Before running the JavaScript unit tests, install the Microsoft Script Control. Before running the Selenium tests, start the Selenium server by running the StartSeleniumServer.bat file located in the JavaScriptReference.QATests project.

Discussion

  1. THanks for this post. Maybe another interesting source for you could be HTML5 Boilerplate framework that also contains a web.config for ASP.net.

    http://html5boilerplate.com/

  2. @Rene – Thanks for the link! Yes, the HTML5 Boilerplate is a great starting point.

  3. Aaron Hillyer says:

    This looks very cool! You show a screenshot of logging in but when I tried to do it, I don’t have an account and it seems that there isn’t anywhere to create one. Can you comment accordingly? Thanks

  4. @Aaron — Thanks for trying out the app! Yes, I didn’t want to make the password for changing entries public because I worry about people the records. You can download the JavaScript Reference app on your local computer and try it (the login is Admin and secret).

  5. AdamA says:

    Stephen, you rock for always sharing your knowledge like this – THANK YOU! I’ve got

    One thing I noticed – it seems you need to give it quite some time to download the data before a search can be performed. I was stuck with my query wondering what button I needed to push – tried ‘enter’ too. A loading animation of some sort or a notice to the user could be helpful, in my opinion.

    Just nitpicking though. I’ve downloaded the project and look forward to learning from it – thanks again!

  6. AdamA says:

    Actually, I just tried it again in another browser and it was lightning quick. Was probably just a slow connection from here.

  7. nice post….thanks

  8. Agboka Sandro a.k.a Akandjo says:

    Stephen, this post is very useful, and i tried it live and it is amazing how fast the application runs even here in Togo (Africa) where our connection speed is 512 kb/s.

    I just wondering how the security of such an application is performed. Since the data is loaded in the client browser, this application will not have security vulnerabilities. If there can be security holes how can we fix them?

  9. Dev says:

    nice stuff , want to know more info about language
    http://www.cprogramming.uniquetricks.com

  10. nikhil jaswal says:

    hey ,great work.much appreciated for your efforts to write down such useful content for us