
I am excited to announce that I’ve refactored (and renamed) my web-centric training course. The old “ASP.NET MVC/HTML/CSS Workshop” was just too long. It’s now called “The Web Workshop”.
This course is concentrating on client-development for the browser. The course will cover client-side development for HTML/JavaScript/CSS development including browser-based sites and mobile browser development. While the course will cover using ASP.NET MVC 3 for doing the server-side code, the focus of the course will be in the client development. This means most of the course will cover the new skills that web developers need including:
- Learning JavaScript
- Using jQuery (and associated plugins)
- Design with HTML5 and CSS3
- How to build pages for mobile browsers
- Working with REST/JSON data
On the server, the course covers the crucial server-side skills:
- Building Controllers and Views
- Unit Testing in ASP.NET MVC
- Exposing Data to JavaScript via ASP.NET MVC
We are holding the first class in Atlanta (GA) February 27-29th if you’re ready to learn how to build create HTML-based clients. There is an early-bird discount of $300 off the course if you sign up by January 30th.
NOTE: While the course could help you build Windows 8 Metro-style apps with JavaScript – it is not specifically covered in the course. We will have a Windows 8 Metro-style courses after the beta!
This is the second of ten parts. The topics will be:
- 1: A New World
- 2: Architecting JavaScript (This Post)
- 3: Debugging JavaScript (upcoming)
- 4: Joy and Pain of jQuery Plugins (upcoming)
- 5: A Better CSS (upcoming)
- 6: Packaging Assets (upcoming)
- 7: Distributed Source Control (upcoming)
- 8: Working with Facebook (upcoming)
- 9: Mobile Pages (upcoming)
- 10: Deploying to the Cloud (upcoming)
Architecting JavaScript
Working with JavaScript can be daunting. In the past, I’ve seen some projects with just a handful of huge files that become difficult to manage. So in architecting what I needed to build, I wanted to adhere to the idea that there was common code and there was view-specific code. There are two different classes of JavaScript that I care about: libraries (e.g. not my code) and site code (e.g. my code).
For now, let’s segregate these two types of code into separate directories as shown below:

The scheme of these directories doesn’t matter, but I decided on keeping the Scripts directory since Nuget packages like to update to the Scripts folder. You’ll see in a later post when I talk about packaging why I separate these. Most of the time I am ignoring “not my code” and opening “my code” quite a lot.
One strategy I’m using is to load all the scripts on every page. Our total size of my scripts is not enormous and I expect that the initial hit of caching the script(s) on the first page will mean that subsequent pages will be faster. I’ll talk about how we are going to package the scripts in a later part of this series, but for now I can just include all the scripts of our project in the ‘master page’ (e.g. _Layout view):
<!-- _Layout.cshtml -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")"
rel="stylesheet"
type="text/css" />
@RenderSection("StyleSheets", required: false)
</head>
<body>
@RenderBody()
</body>
</html>
<!-- We'll use a packager later, don't freak out guys -->
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/js/mwd.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/js/Home.Index.js")"
type="text/javascript"></script>
This means that each page doesn’t need to add their own scripts (in fact, when I package them, I’ll just include all the scripts in the /js/ directory). This should result in less friction at the cost of an initial page load of a larger script which I am not worried about for desktop use (for mobile, I’ll change this strategy as you’ll see in a later part of the series).
Originally I had planned on having a script per page (if necessary) then just including it on the pages required but that meant I needed to be aware of code collisions and inclusion on each page. To combat this a JavaScript namespace can help segment all of my code in it’s own object so I don’t pollute the global namespace. This is just like in .NET where you will create namespaces for your classes. Though JavaScript doesn’t have a namespace as such so a named object is good enough to do the trick:
// mwd.js
(function (m, $) {
m.setStatusMessage = function (message) {
$('#status-message').text(message);
}
} (window.mwd = window.mwd || {}, jQuery));
This works because of line 7 (highlighted). It executes this anonymous function creating the “mwd” object if it doesn’t exist. It passes in this object (as the m variable) so I can add any global data/functions to the object. The first script to run will not find the ‘window.mwd’ object so it will create a brand new object. Subsequent scripts (which will also have this function wrapper around it) will find the ‘mwd’ object and just pass it in. This way every script that uses this convention will add to the namespace object with our code and data. This simplifies the problem of script loading ordering problems and prevent name collision with objects in the global namespace. You can see that in the above that the mwd object is having a new function added to it. Since it’s an object on the window object, we can access this function from any script but only exposing a single global object.
For page specific code, the function wrapper is still used:
// home.index.js
(function (m, $, undefined) {
m.initHomeIndex = function () {
$("#main-section button").on("click", function () {
m.setStatusMessage("clicked");
// This works too
//mwd.setStatusMessage("clicked");
});
};
} (window.mwd = window.mwd || {}, jQuery));
This approach of using an initialization function works as this script just registers the startup function for this page but doesn’t call it. This allows me to call the script on my individual page. This is especially helpful if I need to send in some state to the initialization (e.g. some data from the controller).
You can see the highlighted line is calling a common function that is defined in a different .js file (the mwd.js) and this just works as this code isn’t executed until after all the extensions to the mwd object are already added by all the scripts.
My method for calling the initialization function is to use an optional section on the Layout view that wraps whatever the individual page uses for an initialization (though not all pages will need initialization functions):
<!-- _Layout.cshtml -->
...
<!-- I'll use a packager later, don't freak out guys -->
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/js/mwd.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/js/Home.Index.js")"
type="text/javascript"></script>
@if (IsSectionDefined("Init"))
{
<script type="text/javascript">
$(document).ready(function() {
@RenderSection("Init", required: false)
});
</script>
}
This way if the Init section is defined on a view, I wrap the init code in a jQuery ready call so that it gets called once the page has loaded. The individual view looks like so:
@{
ViewBag.Title = "Index";
}
@section Stylesheets
{
<link rel="stylesheet" href="@Url.Content("~/Content/Home.Index.css")" />
}
@section Init
{
mwd.initHomeIndex();
}
<h2>
Index</h2>
<section id="main-section">
<div>
This is a client-side example!</div>
<button>
Show Message</button>
</section>
<footer>
<div id="status-message"></div>
</footer>
If this were a strongly typed view I could have send date into the initHomeIndex function by JSON serializing onto the page. This allows me to efficiently have my view code added to every view but only call it on the particular views I need it. This is not just for calls that are necessary per view, but could be any shared code as well.
There are other strategies for doing this (as Dave Ward (@encosia) explained using a class on a body tag with the controller and view name) but for our needs this was the most straightforward since we needed initialization data on a number of different views.
This is a pretty universal way of handling this that worked well for me. One thing I ran into was that our Layout view wanted to have some code/markup that was only to be used during release builds (e.g. Google Analytics), I was surprised that Razor didn’t allow me to test for #DEBUG builds. To fix this, I added an extension method to the HtmlHelper class:
using System.Web.Mvc;
namespace ModernWebDev.Helpers
{
public static class HelpHelpersExtensions
{
public static bool IsDebug(this HtmlHelper htmlHelper)
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
}
As this HtmlHelpersExtensions class would probably be a placeholder for a number of extensions for our use, I changed the web.config in the Views directory (not the site-wide one) to include my Helpers namespace on every view:
<?xml version="1.0"?>
<configuration>
...
<system.web.webPages.razor>
<host factoryType="..." />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="ModernWebDev.Helpers" />
</namespaces>
</pages>
</system.web.webPages.razor>
...
</configuration>
This in a convenience and not necessary, but knowing you can add namespaces to every razor view is a great help so you don’t have to annotate a number of @using statements at the top of every view.
I could then use the new extension method to have conditional code in our Layout view:
<!-- _Layout.cshtml -->
...
@if (!Html.IsDebug())
{
<div>Placeholder for Google Analytics</div>
}
What I’ve shown you so far may have some of you scratching your head because the separation of these JavaScript files means that you’re probably not getting any intellisense. I made a decision to just forgo it. If Intellisense is crucial to you, there are some options (none of these were worth my trouble):
- Adding a comment on top of every .js file to the Visual Studio intellisense file to get jQuery intellisense but it didn’t help with overall intellisense.
- Using a 3rd party plugin (e.g. R#) to add the intellisense.
- Use a non-Visual Studio editor (e.g. WebStorm or other editors)
All of these are adequate solutions, but they all seemed to slow down my development and I am an old guy who can get by without it. YMMV.
Much of the process of writing the JavaScript can’t be adequately summarized until we get to the debugging process I used in this project which I will cover in the next part of this series. Good hunting!
Here’s a link to the version of the source code so far:
This is the first of ten parts of this blog post. The topics will be:
- 1: A New World (This post)
- 2: Architecting JavaScript
- 3: Debugging JavaScript (upcoming)
- 4: Joy and Pain of jQuery Plugins (upcoming)
- 5: A Better CSS (upcoming)
- 6: Packaging Assets (upcoming)
- 7: Distributed Source Control (upcoming)
- 8: Working with Facebook (upcoming)
- 9: Mobile Pages (upcoming)
- 10: Deploying to the Cloud (upcoming)
In the past year I’ve had a side project. FirstInked’s Beta recently shipped and I wanted to share with you what I’ve learned. To start out, I want to specifically thank two people who were really great in helping me formulate the strategies I’ll talk about. They are:
- Dave Ward (@encosia) answered every twitter pleading with great advice.
- Chris Rauber (@chrisrauber) was instrumental in doing the initial groundwork on the web project.
Where I Came From
I am not new to website development, but with most of my work taking me into the RIA space five years ago, a lot had changed in the interim. Back 10 years ago, much of the web code I saw and wrote looked a lot like this (and no, my blog code doesn’t look like this):
<html>
<head>
<script type="text/javascript">
function onInit() {
var obj = document.getElementById("foo");
foo.display = "block";
}
</script>
<head>
<body onload="onInit()">
<div id="foo" style="display: none" height="100px">
<font size="3" color="red">Hello World</font>
</div>
</body>
The mixing of the code, markup and styling was the de facto style back then but that doesn’t mean it was a good idea. It was easier with ASP.NET (classic) to do things this way. I relied a lot more on post-backs than client-side code which wasn’t the best experience for users. Something had to give.
What Has Changed?
While I’ve dabbled in Routing and MVC for the server-side code, I hadn’t gotten knee deep into the client-side richness now possible with the likes of jQuery and CSS3. ASP.NET MVC 3 has a lot to offer the web developer, but for this article series I am going to focus in on the client-side story since that is where most of the big changes are (at least in my eyes). I found that in building FirstInked that I spent about 20% of my time on the server code and the other 80% on the client code. This number is undoubtedly skewed by the fact that I am super comfortable with the server code and was learning the client code. But I think those numbers indicate a larger sense of what is happening. If your site isn’t about just displaying information (e.g. just information like a news site or blog) that you will be creating a lot more client-code than back in the first generation of web applications.
An Example
To set some context, let’s take a quick example and build a simple home page using the tools I’ll be talking about.
To start out, I create a new ASP.NET MVC 3 Project. This opens the “New ASP.NET MVC 3 Project” template page:

For any new development I do, I start with an empty project (though the Internet Application can be used if you want authentication and some basic start pages). I will be using Razor and HTML5 so I want to pick both the View Engine and make sure I click the “Use HTML5 semantic markup” checkbox. You can create a unit test project if you like (and you should) but I am going to skip that part for this series.
I start with a simple ASP.NET MVC 3 Empty project (for simplicity). The empty project has no controllers or views yet (though it has a _Layout…e.g. master page using HTML5). I want to clean up the project to be ready for what I want to build.
First, I look in the Scripts folder to see what scripts were added to the project by default. As I won’t be using any of the Microsoft AJAX stuff, I delete them:

I am relying completely on the jQuery stack for my development so the Microsoft scripts aren’t needed.
The next thing I do is upgrade the version of jQuery. The stock ASP.NET MVC 3 ships with the 1.5.1 version of jQuery but using the package manager (assuming you’re using Nuget, which if you aren’t you should be) you can just upgrade both jQuery and jQuery UI which I will use extensively. When you open the “Manage NuGet Packages” dialog, you will want to click on “Updates” to update some of the built-in packages:

I always update the JQuery UI library (since that will update the jQuery library too). You may want to update all the packages, but these are the two that are key to what we’ll talk about. Now that we’ve updated the packages, we’ll need to update the versions on the layout page:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")"
rel="stylesheet"
type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-2.0.6-development.min.js")"
type="text/javascript"></script>
</head>
<body>
@RenderBody()
</body>
</html>
Now that I have the project ready, I want to add a new controller so I right-click the controller folder and add a new Controller:

For my needs I want an empty controller (as the scaffolding of a model doesn’t make sense for this simple example):

This results in a new controller file with a single result for “Index”. To create the view I need to right-click the Index method and pick AddView:

This will bring up the Add View Dialog:

I am leaving the view name so that the controller will find this view when I navigate to it. Again, I am only using Razor for my code so I leave that too. If I were using a model class, I’d use a strongly-typed view but for my needs, no model class. Finally, I want to use MVC 3’s Layout class so I leave the mater page empty. This leaves us with a very simple home view razor file:
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
I am going to focus on the client-side so I won’t put much razor syntax in this file. I have found that keeping a per-view .js and .css file for each page that requires it (not every page will require specialized styling or code, but for this example, I’ll use both). So my new razor file is:
@{
ViewBag.Title = "Index";
}
<link rel="stylesheet"
href="@Url.Content("~/Content/Home.Index.css")" />
<h2>
Index</h2>
<section id="main-section">
<div>
This is a client-side example!</div>
<button>
Click me to add some elements!</button>
</section>
<script type="text/javascript"
src="@Url.Content("~/Scripts/Home.Index.js")"></script>
(For you MVC veterans, you are already thinking ahead, be patient and stop trying to fix problems…we’re going to get to it.)
This is a big part of what I want to show is that separating the concerns into structure, look and code (e.g. Markup, CSS and JavaScript).
Since I am using jQuery, my JavaScript will just add some event handlers via jQuery in the document ready handler:
$(document).ready(function () {
$("#main-section button").on("click", function () {
$("#main-section").append("<div>New Div</div>");
});
});
(Again, if you’re a jQuery veteran…wait for the bigger picture in upcoming posts…promise!)
Finally, I will style the page with some CSS:
#main-section
{
font-size: 85%;
border: black 1px solid;
background-color: #ddd;
width: 85%;
margin-left: auto;
margin-right: auto;
}
Putting this all together, we get a page that handles the mouse click and some basic styling:

You’ll notice that I named the JavaScript and the CSS based on the view and that’s mostly for discoverability while I am doing development. These scripts/stylesheets will be in addition to site-wide scripts and we’ll see later a better way of architecting this. But the general idea to take from this first part is that each view/partialview will consist of mostly these three parts:
- Markup (HTML/Razor)
- Design (CSS)
- Code (JavaScript)
My goal is to finish this series in the next couple of weeks so keep an eye on a part every 2-3 days. You can get the source for what we have so far here:

My company, AgiliTrain, has created its spring schedule and we are happy to announce that we’re going to be expanding with new courses and new cities. Let’s take the courses first.
After much consideration, it seems to me that 2012 is going to be all about XAML *and* HTML5/JavaScript. With this in mind we’re focusing on our two new courses:
ASP.NET MVC 3, HTML5 and jQuery Course
This course is about teaching developers how to build their next generation of web sites. The course includes coverage of:
- ASP.NET MVC 3
- jQuery and jQuery UI
- KnockoutJS
- CSS3 (including using LESS)
- HTML5
- Using Shims and Polyfills for graceful downgrade to older browsers
- Architecting your JavaScript
Web Development for XAML Devs
This new course focuses on taking the skills of existing XAML developers and migrating them to the web. This course includes:
- Comparison of XAML with the HTML/CSS stack
- Structuring JavaScript for Web Sites
- Data Binding with KnockoutJS
- Using MVVM on the web
New Cities
In addition to new courses, we’re also expanding our lineup to include several new cities this year:
- St. Louis, MO
- Boise, ID
- Phoenix, AZ
Our upcoming schedule of courses includes:
Hope to see you at one of our events!

I wasted an evening last night on a simple bug of mine. I was writing a simple HTML data entry page. I was using JSON + $.ajax to POST data to a ASP.NET MVC controller and it used to work. But for the life of me I couldn’t figure out what was wrong. Let’s start with some background.
In ASP.NET MVC3, they made a change to make the JsonValueProviderFactory part of the ValueProviderFactories so that data that comes in as JSON can be mapped to model classes automatically. See this Phil Haack post for how that works:
Essentially the JsonValueProviderFactory is used to match the shape of JSON inputs to model classes. Therefore if you have a piece of JSON that looks like:
{
"id": 1,
"name": "Some Picture",
"picture": "http://wildermuth.com/images/turninghead.gif"
};
And you have an action that looks like this:
[HttpPost]
public JsonResult SaveImage(ImageModel picture)
{
if (picture == null)
{
return Json(new { success = false, message = "Model came through as null" });
}
return Json(new { success = true });
}
The JsonValueProviderFactory’s job is to map the JSON to the ImageModel class:
public class ImageModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Picture { get; set; }
}
It does this by looking at the shape of the JSON and mapping it to properties in the model class. Simple and elegant. Works great…except when it doesn’t.
So how did I lose a full evening to this simple mapping? There are things that can go wrong like not having the routes correct or having bad data sent in the request, but I was reaching the action and my ImageModel was null. No error, no debugging in the output window…it just didn’t work. I stared at this code and cajoled people on twitter to help to no luck. It had to be that the JSON I was sending was incompatible, but I didn’t see how. Fiddler to the rescue.
So I fired up Fiddler2 (www.fiddler2.com) and executed my javascript code that looks like this:
$(document).ready(function () {
$("#send-data").click(function () {
$("#status").text("Saving...");
// Some data in the right shape for the server
var data = {
"id": 1,
"name": "Some Picture",
"picture": "http://wildermuth.com/images/turninghead.gif"
};
$.ajax({
// URI for POST
url: '/Home/SaveImage',
// Turn object into JSON
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
type: 'POST',
success: function (response) {
if (response.success) {
// It worked!
$("#status").text("Saved...");
} else {
//
$("#status").text(response.message);
}
},
error: function (response) {
$("#status").text("Error!");
}
});
});
});
Fiddler captured the traffic and showed what I expected (I can use the inspectors to see both the request and the response as shown here):

You can see the session in the Web Sessions pane. And using the Inspectors, I can see the JSON I sent and the JSON I received (remember on failure, I’m returning a JSON result that explains the failure). Fiddlers let’s you use a tool called the “Composer” that will allow you to create a request and run it directly from Fiddler:

While you could craft a custom request in the composer by just typing all the necessary bits, it also lets you drag a request from the Web Sessions pane to clone it. I cloned the bad request (shown here) and if I press “Execute” it will re-run the request:

Just like the captured request, my re-issuing of the identical request resulted in the model being null. I suspect it has something to do with the property matching in the ModelBinding so to debug this I just removed properties in the JSON request until it worked. Fiddler allows me to use the Composer to just hand-edit the request so I can re-test quickly:

I hand-edit the JSON in the request and remove the picture property. Once I do that (or another part of the JSON request) I can hit execute to see if it still fails:

It worked…huh? Why would removing the picture property make it fail? If we look at the ImageModel class, the property name isn’t misnamed or anything. The solution was obvious once I knew it was the picture property. Let’s see that action again:
[HttpPost]
public JsonResult SaveImage(ImageModel picture)
{
if (picture == null)
{
return Json(new { success = false, message = "Model came through as null" });
}
return Json(new { success = true });
}
The problem is that the name of parameter into the method is picture and MVC is getting confused between wanting to map the picture property of the JSON and the picture parameter of the action. This happens because it would have also mapped our JSON to an action that looked like this perfectly well:
[HttpPost]
public JsonResult SaveImage(int id, string name, string picture)
{
ASP.NET MVC tries to do the right thing and the duplication of the parameter name as the property name got it confused. So to fix this, I simply needed to rename the parameter like so:
[HttpPost]
public JsonResult SaveImage(ImageModel image)
{
if (image == null)
{
return Json(new { success = false, message = "Model came through as null" });
}
return Json(new { success = true });
}
Sure, a wasted night (and the resulting loss of time documenting it here so that you can prop up my fragile ego), but it helped me understand what was really going on under the covers.

A long labor of love of mine has finally been birthed. My Essential Windows Phone 7.5 book is now available for Kindle. You can also pre-order the physical book from Amazon or directly from Pearson. While I’ve been assured that the book is printed, sometimes it can take some time to make it into the retail chain for different outlets. To clear up some of this confusion I thought it would be helpful to tell you how you can get the book depending on which retailer you go with:
Because the book is done printing, some of the retailers that are selling the physical book may ship early so if you want the physical book, pre-ordering is still the best option. If you want to get a hold of it now, Kindle is the way to go.
I hope you enjoy the book.

It’s been a long nine-months and I am excited to be able to talk about what I’ve been working on for the first time. I am working with a small team of people to build a new set of products. But unlike what I’ve been doing in the past, this new set of products is not for developers...
The target of my new project is people who like tattoos (and other body modifications). I found that there wasn’t a good way to share tattoo pictures on the web and on Facebook. That’s what I am tackling. By the end of the year I will be launching this new web application to help people do just that.
This new venture is going for full reach of users. Unlike a typical line-of-business application, this application has to reach the users where they need us. That means we are targeting a wide berth of platforms:
- Desktop Website
- Mobile Website
- Facebook Application
- Mobile Apps (iOS, Android and WP7)
Our first milestone (to be delivered soon) will be the desktop web version of the product. When the project was started, we had an important decision to make: what platform to choose. We spent some time digging into Ruby, PHP and MVC3 for the web platform. We also spent some time with NoSQL databases to see if they were a good fit for what we needed. At the end of the day my familiarity with the Microsoft stack left me there. Is it perfect, no…it is very usable? Yes.
The Server
The goal of the web platform was simply to get out of our way. On the server, we went for a pretty standard set of tools:
- ASP.NET MVC3
- Ninject for Dependency Injection
- SQL Server 2008 for Relational Storage
- Entity Framework Code First for Schema Design/Data Access
- ELMAH and Glimpse for Error Handling
- AutoMapper for mapping models to entities
- Squishit for JavaScript/CSS Packaging
- Amazon S3 for Blog Storage
- AppHarbor for Cloud Hosting
- Facebook SDK for Facebook Integration
Some of you may be thinking about our decision to use the Entity Framework for a public facing website where speed and load may be issues. Our goal here was to use the power of Entity Framework’s Code First functionality to help us build our data schema quickly. Remember, we’re a small team so that while ceremony could help us as we grow, we did made some key decisions to speed up development knowing we would be able to refactor it later on. For example, even though we’re using Code First, we kept the data shapes and data access separated from the code so that we could refactor that later (side note: we’ve prototyped going to Dapper as our object builder and we can do it with little change to the code).
An interesting lesson we’ve learned is that since we’ve got a lot of experience with .NET, the server code ended up being 20-30% of the work. The balance of the work was in the client-side development. Now if you’ve been following me the last 1/2 decade, you may be wondering if Silverlight has a story here in the client-side development. In our case, no. Remember, we’re building a set of web sites that have to reach as many people as possible so Silverlight would simply get in the way of that goal. Like I’ve said before, HTML is for sites; Silverlight is for apps.
The Client
On the web side, we’re building HTML5/JavaScript pages. We’ve used quite a few frameworks. These include:
Managing the Project
Our team is a small, but distributed team of people in different time zones. In order to work with the project in a simple way, we needed several things: source control, project management and bug tracking. The tools for the job for us are:
These tools worked well together to help us plan and build our project. What I found interesting is that these tools were all fairly low (or no) cost to get started. FogBugz and BitBucket both have free tiers to help you get started. AgileZen is free for open source projects and I think only $9/month for up to three projects. So the cost of getting started is simply tiny. This was a big help for us.
We’re still very small so there are some missing pieces but for the most part the project has come together with the tools and frameworks staying out of our way.
For me personally, development would have been faster if I had deeper knowledge of the client stack, but it’s been a great way to learn all these great ways of building client-side, rich web pages.
If you have or want tattoos (or piercings or other body modifications) and want to help us beta test the project, head over to the teaser page and join the list of beta testers:
Let me know what you think!
I buy a lot of music. I am not a hoarder like some, but I have 100GB’ish of MP3s. I don’t go around and ‘borrow’ friends collections just to up my count. What I do is buy music…just not at brick and mortar stores.
While I could go on about how iTunes on Windows is a bad piece of software, that’s not what I care about. It’s the DRM. I pave my machines constantly and I have my music on a lot of devices at once. Music Match sounds like a good idea, but Apple has burned that bridge with me a long time ago so I won’t harp on it. But as a consumer of music (and someone who wants to support the artists), what do I do?
Buying Music
Amazon MP3 and CD Baby are what I do. There are other services, but this is how I buy music most of the time. I haven’t come across an album I want I can’t get this way. I am sure there are some iTunes exclusives, but it hasn’t happened in a long time. These works for me because they give me MP3s like I want. I could get other formats if I were an audiophile (but I am old enough to have lost enough dynamic range that I am not sure I could tell the difference any longer).
Playing Music
My main media player isn’t an iPod or even my phone…it’s my laptop. So I use Zune to play music. Yeah, it’s a bit bloated but it’s support for playlists of songs I have ‘hearted’ and for time-based playlists (e.g. songs I’ve added in the last sixty days) solves most of my issues. I play music on my phone when traveling and syncing there is pretty painless. If I didn’t have a Windows Phone, I’d just use Media Monkey to sync to other devices as it has great device support and is the best tool to clean up your MP3 metadata tags.
Backing Up My Music
When talking to my friends who cling to vinyl and CD cases, I get asked a lot about what happens when my hard drive crashes. I have a several pronged approach here…most people need just one of these, but do several just in case:
- Use SyncBackSE to copy my library to my house file server for safe keeping (and sharing with my Media Center PC).
- Use JungleDisk to backup all my files (including music) to Amazon S3 store I have.
- Use Amazon Cloud Drive to back up all my music to a second place (see below for why). This is $20/year for 20GB + all the music you can upload.
This allows me to be sure my music is completely safe, no matter what happens. If I were more fearful, I might save it to Skydrive or other online drive just in-case…but I think this is enough ;)
Cloud Listening
Lastly, I usually listen locally but since it was free I backed up all my music to Amazon Cloud Drive specifically to support Amazon Cloud Player. This let’s me open any browser and play music. And, yes, there is an app for iPad to play your music. Since I have a Kindle Fire, support comes built-in for playing my whole collection (or cache my favorites to the device for offline use).
What do you do?
As most of you know, I have been in the Silverlight space for quite a while. (And to be clear to the chicken-little amongst you, no I am not leaving the Silverlight community.) I’ve been building a web application for consumers so that HTML + JavaScript represents the right solution to building a project like we’re building (more on what I am building in the near future).
One of the things I wanted to be able to do is to build longer-lived pages where it made sense without having to resort to post-backs or hacked together JavaScript. In fact, what I really wanted was a client-side ViewModel (e.g. MVVM) for my web page. After looking at several of the existing frameworks for the job, I settled on KnockoutJS as a great solution. The currently released version (1.21) is a good solution, but the developers of the framework have released a Beta (1.3Beta) version that greatly simplifies what I needed. If you want to follow along, make sure you download that version here.
To get started, I simply have a database of Xbox games (yeah, I know). I am using ASP.NET MVC3 for the web part. I’ve got a single page that contains a drop down of genres and a REST-call from the MVC Controller that returns the games for a particular genre. You can look at the code if you’re interest in that part of the story. I am going to focus on the client-side JavaScript.
The first thing I needed was to add the KnockoutJS file into my project. If you go to this blog entry, you can download the JavaScript file to include in your project:
Note that there is a KnockoutJS Nuget package but it includes the 1.21 version currently. For this example, I am using the 1.3 version instead so you’ll need to get it manually.
Next I created a simple view and included Knockout on the page:
<script type="text/javascript" src="/Scripts/knockout-1.3.0beta.js"></script>
I also wanted to separate the JavaScript from my view (note the separation, like I am used to in Silverlight and a great suggestion by Dave Ward). So I created a separate JavaScript file and included it:
<script type="text/javascript" src="/Scripts/view.js"></script>
In the Controller, I am retrieving a list of genres and then simply creating a DropDownList with the results of the Genres:
<div>
@Html.DropDownList("genres",
Model.Select(g =>
new SelectListItem()
{
Text = g.Name,
Value = g.GenreID.ToString()
}),
"(none)")
</div>
This is all pretty standard ASP.NET MVC so I won’t belabor explaining it.
What I wanted was to have a list of games show up when the user picked one of the genres. I can accomplish this by using KnockoutJS and jQuery
KnockoutJS is a framework that allows me to use HTML-based data binding markup to describe my UI, CSS to describe what the design looks like and JavaScript to tie the data to the data binding. The is chiefly accomplished through the concept of observable objects. For example, I created a new JavaScript ‘class’ called gameModel in my view.js by creating members using the observable method on the knockout (e.g. ko) object like so:
// view.js
$(document).ready(function () {
function gameModel() {
this.name = ko.observable();
this.id = ko.observable();
this.genre = ko.observable();
this.releaseDate = ko.observable();
this.price = ko.observable();
this.imageUrl = ko.observable();
};
...
});
The observable call returns an object that not only can store a property, but let the KnockoutJS binding stack know when the property changes (two way binding). In order to use the gameModel ‘class’, I created a view model to store a collection of gameModels like so:
// Define Main ViewModel
var theViewModel = {
games: ko.observableArray([]),
...
};
The games property of the view models ‘class’ will hold the current list of games that are shown in the UI. The observableArray object is like the observable object but it notifies the data binding stack when a collection changes. The goal here is to have the view model load the games from the REST service and as the collection changes, the HTML should change to react to that. No more manually creating/destroying parts of the markup.
In order to make this work, we must use the data binding syntax in the HTML code:
<div data-bind="foreach: games">
<div class="game-block">
<div>
<img data-bind="attr: { src: imageUrl, alt: name }" /></div>
<div class="game-name" data-bind="text: name">
</div>
</div>
</div>
KnockoutJS uses an attribute called “data-bind” to specify the data binding for a particular element. The syntax is fairly straightforward but let’s look at it from the inside-out:
<div class="game-name"
data-bind="text: name">
</div>
The “text” tells KnockoutJS the type of binding you want. In this case, we want to fill the text of the div with the name property (e.g. the observable object) on the model (gameModel in this case). There are several built-in binding types but it is extensible if you need something custom. These include (but these aren’t all of the binding types):
- visible: Expects the value to be Boolean as to whether an item is visible or not.
- text: Sets the text of the element (logically…e.g. innerText for divs; value for input).
- html: Displays the HTML as the inner part of an element.
- css: Sets the element’s CSS class.
- style: Sets specific CSS style properties on the element.
- attr: Sets attributes on the element.
For example, the attr binding is used to set attributes of the image based on properties of the model:
<div>
<img data-bind="attr: { src: imageUrl, alt: name }" />
</div>
In this example, the src and alt attributes of the img tag are set to properties of the model.
We now have data binding based on the model class, but what about the collection? This is where the data binding syntax of KnockoutJS (specifically 1.3 and later) is so simple and powerful. There is a data binding called foreach. This data binding will repeat what is inside an element based on a collection:
<div data-bind="foreach: games">
<div class="game-block">
<div>
<img data-bind="attr: { src: imageUrl, alt: name }" /></div>
<div class="game-name" data-bind="text: name">
</div>
</div>
</div>
In this case, the entire game-block is repeated for each item in the games collection of the view model. If there are no items in the collection, the element will be empty. To tie the view model to the view, back in the JavaScript (view.js), you simply need to call the KnockoutJS applyBinding method:
// Bind it to the UI
ko.applyBindings(theViewModel);
So you might be wondering about how you get the change of the DropDownList to work? KnockoutJS does have a way to data bind events, but depending on the style of JavaScript you like – you may choose that. I find that the simple jQuery event handling is just simpler:
$('#genres').change(function (event) {
var genreId = $("#genres option:selected").first().val();
if (genreId !== null) {
theViewModel.loadGames(genreId);
}
});
In this case, we’re just using jQuery to wire to the change event and if the genreId isn’t null (e.g. the user picked something) we call the loadGames method of the ViewModel. Even though I’m using jQuery for the event, we’re still leaving the actual work in the view model as that helps centralize it for me. But you may be wondering about the loadGames method since I haven’t shown it yet. Here’s the view model:
// Define Main ViewModel
var theViewModel = {
games: ko.observableArray([]),
loadGames: function (genreId) {
var url = "/Sample/GetGamesByGenre?id=" + genreId;
$.ajax({
url: url,
success: function (response) {
if (response.success) {
theViewModel.games.removeAll();
$.each(response.results, function (x, game) {
theViewModel.games.push(new gameModel()
.id(game.Id)
.name(game.Name)
.releaseDate(game.ReleaseDate)
.price(game.Price)
.imageUrl(game.ImageUrl)
.genre(game.Genre));
});
} else {
alert(response.message);
}
},
error: function (response) {
alert("Failed to get games...");
}
});
}
};
The loadGames just uses a jQuery ajax call to get the data from REST service. The response (if successful) is just a collection of objects. I first call the removeAll method on the collection to make sure it’s clear before we fill it, then push a new gameModel ‘class’ onto the colleciton for each element of the results. Once convention you’ll have to get used to with observable is that you don’t assign the values, but you execute the function that is the property to assign the new value:
// do
game.id(1);
// not
game.id = 1;
Assignment supports chainging (e.g. fluent syntax) so creating a new instance of the gameModel class is like so:
new gameModel()
.id(game.Id)
.name(game.Name)
.releaseDate(game.ReleaseDate)
.price(game.Price)
.imageUrl(game.ImageUrl)
.genre(game.Genre));
The current version of KnockoutJS (1.2.1) works great too, but the templating syntax described here (e.g. foreach) isn’t in that build. Instead they rely on jQuery Templates so the examples you see out there will look a little different than this.
KnockoutJS has some great links that I want to point you to:
You can get the full source (including the database) here:
So the Windows Phone Marketplace hit 40K apps. What does it mean to the platform? There are a number of articles out there that talk about the 40,000 apps and compares them to other platforms but I think they are missing a key differentiator.
Articles like the PC Magazine article point to the fact that Apple got to 50K in one year (faster than Microsoft) and that it took Android in 18 months (a tad slower than Microsoft). But to me the real remarkable news of this milestone isn’t the speed…it’s the size of the marketplace for that is astounding in my opinion.
Let’s look at the numbers. According to Garner, the 2011 Q3 numbers indicate that the worldwide market share for smartphones is (see Table of the report):
- Android: 52.5%
- Symbian: 16.9%
- iOS: 15%
- RIM: 11%
- Bada: 2.2%
- Microsoft: 1.5%
- Others: 0.9%
Note that is worldwide. Apple and Microsoft have better market share for the US market alone.
Why is this important? A platform that in it’s first year only got to 1.5% of the smartphone market was able to get the developer ecosystem excited enough to build and deploy 40,000 apps. How big will it be if the world’s largest handset (not smartphone) manufacturer succeeds in getting the world to buy WP7 devices? Wow…
Admittedly, I am invested in WP7 (book, classes, fandom, etc.) so I am apt to be excited by anything that improves our 1.5%. What excites me is that we got to 1.5% without Nokia. Nokia is an impressive brand…just not so much here. Where is it big? in 2/5ths of the world. When you look at China, India and Japan you find that those are monster markets. If Nokia even has mediocre success, that could change the balance. when you’re talking about 2.7 billion people. These three countries represent the 1st, 2nd and 10th biggest populations in the world. That’s 38% of the world population.
I know that population numbers aren’t strictly indicative of market size, but when you’re talking about numbers this big, even a smaller percentage of users of phones in these countries (ignoring Japan in this case), we’re still talking about much larger markets than the US or Europe.
I hope I am right…