It was fun while it lasted
On Tuesday at Google I/O, the AppEngine team announced a new pricing structure. When AppEngine comes out of beta later this year, the pay for usage plan will be removed, even for existing applications. A free tier will still exist, but the quotas will be greatly reduced and you cannot pay more more outside of the free quotas. I guess this means that if you use up all of your datastore API calls (50K per day) then you can’t make anymore calls until the quota resets (at midnight pacific time). Also, now AppEngine will bill for instance hours and not CPU hours. So basically if you have one instance running for one hour it will cost you 8 cents. I don’t know what the increment will be yet but I am worried it will be 15 minutes increments like the new backends feature. There is a way to get 5 cents per hour by purchasing reserved instances but this is still $36/month per instance. On top of that, there is a $9 per app fee (per month) for which you get nothing. You still have to pay for bandwidth, storage and other APIs with no allotment. This could get very expensive. The web is not happy about it either. Some people have accused Google of bait and switch. I don’t think they were aiming to do this from the start. In my opinion, they realized they couldn’t sustain profits with the pay for usage plan and this was the only way they could keep AppEngine around. Also, they announced that Go (a hybrid of Python and C++ invented by Google) can now be used with AppEngine. This is worthless is my opinion. It means that either Go was invented for AppEngine or because of the popularity of AppEngine this is a last ditch effort to keep Go alive. As a result of the new pricing structure, AppEngine may not be so popular anymore. One piece of good news, with SDK 1.5.0 now any owner of an application can download the code instead of the owner that uploaded it. I am really wondering if I have much incentive not to switch to Azure now.
Create Graphics in All Browsers with Raphael.js
In the web browsers of recent years, the feature of creating graphics using JavaScript has been the topic of much interest. One such solution is the HTML5 canvas which is still in development though many browsers support at leat some of the specification. However, since the spec in still not finished, the implementations are inconsistent. Microsoft attempted to make VML (Vector Markup Language) but it only made it into Internet Explorer. The W3C has create SVG (Scalable Vector Graphics) which it becoming the most popular implementation and is in every major browser except Internet Explorer. We can get similar output using both. We need a bridge to take the same input and produce VML or SVG depending on the browser. If this seems like a major undertaking, you are correct. However, Raphael.js does this for us.
To use Raphael, you obviously have to import the .js file with the framework. The next step is to create a surface for Raphael to draw on. There are two ways to do this. First you can specify the absolute coordinates of the surface, or you can specify an element to place the surface in:
// create a 500px by 500px surface at (25, 25)
var surface = Raphael(25, 25, 500, 500);
// create a 500px by 500px surface in the element with id "surface"
var surface = Raphael(document.getElementById("surface", 500, 500);
To create graphics on the surface, you call methods on the surface. Let's draw a circle:
var circle = surface.circe(200, 200, 100);
This will create a circle with a 100px radius with the center 200px to right and below the origin which is the upper left corner of the canvas. The default color for the outline of the circle is black and no fill color. This can be changed with the attr method on the graphic element:
circle.attr("stroke", "#0000ff"); // change the outline color to blue
circle.att("fill", "#00ff00"); // change the fill color to green
You can also set multiple properties in one call putting them in an object:
circle.attr({stroke: "#0000ff", fill: "#00ff00");
As one could assume, there is also method for creating rectangles:
// create a rectangle with the upper left corner at (200, 200) and 100px wide and 200px high var rectangle = surface.rect(200, 200, 100, 200);
The attr method works on rectangles the same as on circles.
For lines, there is no method. Instead, you call the path method and pass SVG path data to the method:
// draw a line from (100, 100) to (200, 200)
var line = surface.path("M100 100L200 200");
M is for "move" and L is for "line" so this reads:
"move to point (100, 100) and then draw a line to point (200, 200)"
While creating circles is simple, creating arcs takes some math. To draw a 90 degree arc with a radius of 70 px and a center at (150, 150):
var arc = surface.path("M150 80A70 70 0 0 1 220 150");
Read this as
- Move to point (150, 80)
- Draw an circular arc convex with a 70px radius that passes through point (220, 150)
The A command in the SVG path data takes the length of the x and y radii and then two parameters which I will not explain now because they have no bearing if the x and y radii are the same length. The next parameter draw a convex arc if it is 1 and concave if it is 0. The last two paramters are the finish point of the arc. You have to determine the cosine and sine of the angle of the arc and then multiple by the radius to get the point on the circle where the arc stops. Then move the point by the offset from the origin to compensate for the translation between the coordinates.
But the really cool part of Raphael is how you can interact with and animate elements. I'll get into that in the next post.
Node.js–Introduction
Lately, I have been playing with Node.js. Node.js is a server-side JavaScript framework built on the V8 JavaScript engine developed by Google for Chrome. Through the framework, system services are accessible which are designed for use in writing small, scalable network applications. I’m going to demonstrate a few of these services by writing a small web server (not the one you see as the Node.js ‘Hello World’)
The first thing we need to do is import the module that handles HTTP traffic. This is creatively named ‘http’. To import the http module use this code:
var http = require('http');
The require function is not part of JavaScript. It is in the CommonJS API and implemented by Node.js. It is similar to using in C# or import in Java. However, the require function returns an instance of the module imported. Later on we’ll import a few more modules but this will work for now.
The http module has a function, createServer, that presumably creates an instance of an HTTP server. The instance is of the http.Server object. The createServer function takes one parameter, a callback function. In Node.js, the idea is that everything is handled with events. In other words, the createServer function will return immediately, and then the callback function will be hooked up to the request event which will mean data is coming into the server. When the request event is activated, the callback function will be called.
The signature of the callback function is two arguments. The first is the request from the browser (type ServerRequest) and the second is the response sent to the browser (type ServerResponse). Inside of the function, we will set the status and the headers, and write some data back to the browser:
var handleHTTPRequest = function(request, response) {
response.writeHead(200, {'content-type': 'text/html'});
response.end('Hello Node!');
}
var server = http.createServer(handleHTTPRequest);
In the docs for the writeHead function, there are three parameters listed. The headers are the third parameter but we don’t need to pass null to the function. JavaScript is dynamically typed so Node will look at the second parameter and if it is an object it will assume that is is the headers.
The only thing left to do is tell the server to accept incoming connections. This is done by calling the listen function on the server object. It will take one parameter, the port on which to accept connections:
server.listen(3000);
Now at the command line (I am using an Amazon EC2 instance) run the server and visit the base URL for your server in a browser:
> node httpsvr.js

This is a start but it is not very useful. The ‘Hello Node!’ message will be displayed not only for the root URL but any URL. We need to be able to serve pages. Lets’ fix that.
To start, create a directory called www where the pages will be stored. In that create two files: index.html and about.html. The content doesn’t matter as long as you can tell them apart.
The next step is to import a few more modules:
var fs = require('fs');
var url = require('url');
var path = require('path');
The fs module contains objects and function for the file system. The url module handles URL parsing and the path module emulates some UNIX functions that work with path names.
Change the callback function to look for the file requested:
var handleHTTPRequest = function(request, response) {
var _url = url.parse(request.url);
var resource = path.basename(_url.href);
fs.readFile('www/' + resource, function(error, data) {
if (error)
throw error;
response.writeHead(200, {'content-type': 'text/html'});
response.end(data);
}
};
The readFile function takes two parameters. The first is the path of the file to read and the second is a callback function. The callback function takes two parameters. The first is an object that will have error data if an error occurs (we’ll use this to send 404 responses in a minute) and the data in the file to read. We use the url and base modules to parse the name of the file out of the URL. The url module has the orginal URL without the querystring in the href property and the basename function will return only the filename. The rest we have seen before.
This works but if we request a page that does not exist, the application crashes because we are throwing an unhandled exception. To fix that, we will look at the error code and if it is ‘ENOENT’ it means that the file could not be found. Then we send a 404 status code and redirect the user to an error page. First, in the www directory create a page called 404.html and put some kind of witty error message in it. Then, modify the code in the beginning of the readFile callback function:
if (error) {
if (error.code == 'ENOENT') {
fs.readFile('www/404.html', function(error2, data) {
response.writeHead(404, {'content-type', 'text/html'});
response.end(data);
});
} else {
throw error;
}
} else {
response.writeHead(200, {'content-type', 'text/html'});
response.end(data);
}
We just bail if the error code is something else.
Now when we go to index.html and about.html we see the different pages. If we go to a page that does not exist, such as bogus.html, we get the custom 404 page.



Using the built in developer tools in Chrome, we can confirm that for bogus.html a 404 code was sent:

Actually, if you were to write a real web application with Node.js, it is better to use a framework such as Express. I’ll get into that in the next post. It’s also helpful to have an idea of what is going on at the lowest level first. Still, it is not hard to write servers using just Node.js.
ASP.NET WebMatrix Part 1
The best way to learn a new technology is to do something with it. The last couple of posts I have made on ASP.NET Web Pages have been more of an intro to features instead of showing something practical. While the application I am going to build in this series is not production ready, it will show off the features in an application.
The application I am going to build is a simple address book. When I say simple, I mean it. An address in this case consists of a first name, last name, and email address. The application will show a list of addresses, create new address, edit addresses and delete addresses. In this first part we will set up the project, create the database, make a few pages and get the list to work.
Setup the project
The first thing to do is open WebMatrix in the Start Menu:

Assuming you have not changed the default settings (or this is the first time you have started WebMatrix) you will get a splash screen with these options:
(Click picture for larger version)
We are going to select “Site From Template” and be presented with the following dialog:
(Click picture for larger version)
Select “Empty Site”, give it a name of “AddressBookDemo” and click “OK”.
Create the database
We are now ready to create the database. In the lower left corner of the window are some options. Click on “Databases”:

Next click on the “New Database” button in the ribbon bar at the top of the screen:

A new database will be created under AddressBookDemo. The default name is “AddressBookDemo.sdf” but you can change it. I am going to leave it and just press Return.

Make sure the “Definition” button in the ribbon is clicked:
The next step is to create a new table. At the top of the window in the ribbon bar is a “New Table” button. Click it to create a new table in our database:

This will open up the table designer:
(Click picture for larger version)
In this dialog, we will define the structure of our table. As I said before, the address will be very simple with just a first name, last name and email address. Also, the database will want an ID which will just be an auto incrementing integer.
Click to the right of “(Name)” in Column Properties at the bottom of the designer. Type in “ID”. Use the drop-down next to “Data Type” to set the type to “int”. Do the same with the drop-downs next to “Is Identity?” and “Is Primary Key?” to set them to True. When creating a primary key, WebMatrix will set “Allows Nulls” to False.
Next click the “New Column” button at the top of the window:

Repeat the steps above (with the exception of setting the primary key and identity) to create three more columns:
- FirstName, type nvarchar (leave the length default of 100)
- LastName, type nvarchar
- EmailAddress, type nvarchar
Next, click the “Data” button and fill in the table as follows:

(Click picture for larger version)
Save the table by pressing Ctrl+S. Name it “Addresses”.

Folder structure
With the database set up, we can create the folder structure for our application. There will be two folders in the root: Shared for common files, and Styles for stylesheets. Click on the Files option in the lower left of the window:

Right click on the “AddressBookDemo” folder, and select “New Folder”:

Name the folder “Shared”. Repeat for “Styles”.
Create the stylesheet
The new stylesheet will be called “Site.css”. To create it, right-click on “Styles” and select “New File”:
(Click picture for larger version)
Select “CSS” and name the file “Site.css” and click “OK”:
(Click picture for larger version)
Add the following to the file:
* {
/* Poor man's reset */
padding: 0;
margin: 0;
font-family: Arial, sans-serif;
font-size: 12px;
}
div#top-menu {
border-bottom: 1px solid #ccffcc;
padding: 0 0 0 10px;
}
div#top-menu ul {
list-style-type: none;
}
div#top-menu ul li {
display: block;
float: left;
}
div#top-menu ul li a {
text-decoration: none;
color: #000000;
font-weight: bold;
padding: 10px;
display: block;
}
div#top-menu ul li a:hover {
color: #006600;
background-color: #ccffcc;
}
.clear {
clear: both;
}
.listFirstName, .listLastName, .listEmailAddress, .listEditButton, .listDeleteButton {
display: block;
float:left;
width: 200px;
}
.columnHeader {
font-weight: bold;
font-size: 16px;
color: #006600;
margin: 0 0 10px 0;
}
.addressDisplay {
margin: 10px;
}
h1 {
font-size: 34px;
font-weight: bold;
color: #006600;
}
Create the layout
Right-click on the “Shared” folder and select “New File”. Create a new .cshtml file called “_Layout.cshtml”. This will be the base page for our application. Add a reference to our stylesheet in the head tag:
<link href="@Href("/Styles/Site.css")" rel="stylesheet" type="text/css"/>

Next, in the body, add the following code:
<div id="main_content">
@RenderBody()
</div>

To see our layout page in the browser, create a new .cshtml file in the root of the application and call it “Home.cshtml”. Replace the contents of the page with the following:
@{
Layout = "/Shared/_Layout.cshtml";
}
<div class="addressDisplay">
<h1>Address Book</h1>
</div>
This should be familiar from my previous post about sectional content in Razor. What we have done is assigned the _Layout.cshtml to be our layout file. Then when RenderBody is called in the layout file, it will insert the markup in Home.cshtml. Next, click on the Home.cshtml file in the file list on the left side and click the “Run” at the top of the window:

It looks like this in the browser:

Adding the menu
To make things a little more interesting visually, we will add a navigation menu at the top of the layout page. In the “Shared” folder, create another .cshtml file and call it “_Menu.cshtml”. Replace the contents of the file with the following:
<div id="top-menu">
<ul>
<li><a href="/Index">Home</a></li>
<li><a href="/Create">Create</a></li>
<li><a href="/List">List</a></li>
</ul>
<div class="clear"></div>
</div>
This should appear at the top of every page so we need to have it render in the layout file. Add the following after the body tag in _Layout.cshtml:
@RenderPage("/Shared/_Menu.cshtml")

Since we are referencing this file by name, we use the RenderPage helper as described in my previous post. The result (when combined with the CSS) is the following:

Creating the list view
For the last part of this post, we will create the list view. You might have noticed that all of the URLs for the links in the menu have no extension. This is a nice feature of ASP.NET Web Pages that lets us create cleaner more SEO and bookmark friendly URLs. The list view will be in a file called List.cshtml in the root folder (go ahead and create it) but we can access it at either /List.cshtml or /List. Also, we can access the Home view at either /Home.cshtml or /Home. I am using the latter as you can see in the menu.
Remove all the contents of the list view and put the following code in:
@{
Layout = "/Shared/_Layout.cshtml";
var db = Database.Open("AddressBookDemo");
var queryList = db.Query("select * from Addresses");
}
The first line should be self-explanatory. The second line uses the Open method on the built-in Database object to create a connection to our AddressBookDemo database. Then we perform a SQL query on that connection object the retrieve all of the rows in the Addresses table.
The rest of the list view is this:
<div class="addressDisplay">
<div class="listFirstName columnHeader">First Name</div>
<div class="listLastName columnHeader">Last Name</div>
<div class="listEmailAddress columnHeader">Email Address</div>
<div class="listEditButton columnHeader"></div>
<div class="listDeleteButton columnHeader"></div>
<div class="clear"></div>
@foreach(var address in queryList) {
<div class="listFirstName">@address.FirstName</div>
<div class="listLastName">@address.LastName</div>
<div class="listEmailAddress">@address.EmailAddress</div>
<div class="listEditButton"><a href="/Edit/@address.ID">Edit</a></div>
<div class="listDeleteButton"><a href="/Delete/@address.ID">Delete</a></div>
<div class="clear"></div>
}
</div>
The first set of DIVs are the column headers. Then, using Razor syntax, we use a foreach loop to get each row in the query. The query is a ReadOnlyCollection instance. Within the loop, we can use Razor syntax to easily access the properties of each address. When combined with the CSS, we get this result:
(Click picture for larger version)
Setting the default page
That’s almost it for this part. We need a final thing though. The default page for the application needs to be Home.cshtml. Click on “Site” in the lower left of the window:

And click “Settings” in the pane:

The site settings will appear:
(Click picture for larger version)
In the Manage Default Pages section, at the bottom, type Home.cshtml into the textbox and click “Add”:
(Click picture for larger version)
Home.cshtml is now at the top of the list and will be the first default page for the application.
The End
There is a lot more that WebMatrix can do. In the next part, we will round out the editing of the database. Please feel free to leave comments and concerns.
Source code: AddressBookDemo.zip
Razor Syntax–Sections
My last blog post about Razor was a general intro to the syntax. In this post, the concept of sections and layouts will be explained. It is similar to the master pages in ASP.NET Web Forms and ASP.NET MVC ASPX views. This will be in the context of ASP.NET WebMatrix.
Layout Files
In Razor, a file for a layout has a .cshtml extension. Inside of the file will be the HTML for the base of the layout, with HTML Helper directives to indicate where content should be imported and what content. Here is an example:
<html>
<head>
<title>Layout</title>
</head>
<body>
<h1>My Layout Page</h1>
<div id="content">
@RenderBody()
</div>
</body>
</html>
This is a normal HTML page with the exception of the RenderBody directive. This is a HTML Helper that tells the layout page to render the content of the page for which this is a layout. Here is the content page:
@ {
Layout = "/Shared/_Layout.cshtml";
// we have to use the semicolon after a statement in a code block
}
This is the content.
It is convention to begin layout files with an underscore (_) and to place them in a Shared folder.
If this file is named page.cshtml, it will look like this in the browser:
The _Layout.cshtml rendered the content of page.cshtml in place of @RenderBody(). We can do more complex things as well. What if we need a common navigation element on each page?
<div id="menu">
<ul class="top-menu">
<li><a href="#">Home</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
<li><a href="#">About</a></li>
</ul>
</div>
Just after the line with the <h1> tag in _Layout.cshtml, place the following:
@RenderPage("/Shared/_Menu.cshtml")
To make the page look a little better, create a stylesheet called Site.css and put in a folder called Styles in the root folder of the site. Here is the file:
ul.top-menu {
list-style-type: none;
}
ul.top-menu li {
display: inline;
}
ul.top-menu li a {
color: #000000;
text-decoration: none;
}
ul.top-menu li a:hover {
text-decoration: underline;
}
Back in _Layout.cshtml, place this tag in the <head> to import the stylesheet:
<link href="@Href("/Styles/Site.css")" rel="stylesheet" type="text/css"/>
The result is something like this:
The @Href helper creates an appropriate path to the file passed to it.
The last thing to look at in this post is sections. Sections are pieces of named markup. You define them with the @section directive like so:
@section logo {
<div id="brand">
<img src="@Href("/Shared/Site.css")"/>
</div>
}
This would go in the page.cshtml file. In the _Layout.cshtml place the following after <div> with RenderBody():
@RenderSection("logo")
The page now looks like this:
So to summartize:
- The _Layout.cshtml is the “shell” for a page
- Layout pages are specified in content pages by assigning the Layout property in a code block
- The @RenderBody() helper will render the markup of the content page
- The @RenderPage() helper will render the content of a specified file
- The @RenderSection() helper will render the content of a named section in the content page
- Sections are denoted with @section section_name { markup }
There is still a lot more to go. The next time I’ll talk about creating your own helpers.
jQuery Deferreds
Recently, jQuery version 1.5 was released and one of the most obvious new features is an object called Deferred. The purposes of Deferred are:
- Register multiple callbacks for functions
- Monitor the state of those functions
- Aggregate the state of several functions
I have a demo set up on JSFiddle at:
http://jsfiddle.net/poweredbyaltnet/NcseB/
This is a variation of a demo by Eric Hynds that will show the sequencing of events and callbacks.
There are several ways to create a Deferred. The first is by using the Deferred() method of the core jQuery object:
var deferred = $.Deferred();
The Deferred object will have several methods for defining callbacks, querying the state of the object and for setting the state of the object. There are two states that a Deferred can have: resolved and rejected. After creation, it has no state. After the state has been set, the state of the object can be checked using the isResolved() and isRejected() methods. These will return undefined is the respective state is not set and an Object otherwise. To set the state of a Deferred, use the resolve() and reject() methods.
The callbacks that are called depend on the state of the Deferred object. There are three methods used to set callbacks:
- done
- fail
- then
The done() method sets the callback/s for when the Deferred is resolved. The fail() method sets the callback/s for when the Deferred is rejected. The then() method sets both. All methods take either a single function or and array of functions (two in the case of then()).
In the sample on JSFiddle, I am calling the when() method on the core jQuery object. Inside of that I call two functions each of which return a Deferred. The when() method will create a new Deferred object that basically ANDs the state of the returned Deferreds. If all of the Deferreds are resolved then the master Deferred will be resolved. If one of them is rejected, then the master will be rejected.
The when() method returns immediately. Then you’ll see that after one second f() is called and then after another second g(). Then both Deferreds are resolved so the master is resolved as well. If you re-run the example and check “Reject F”, then both f() and g() will still be called, but since the first Deferred is rejected, the error message will be shown before g() is called.
Everyone’s favorite example of Deferreds is for Ajax. Starting with jQuery 1.5, the $.ajax() method returns a Deferred instead of an XHR. This way you can queue up several Ajax calls and process tem only after you know they have all completed. If one fails, you can rollback the entire process.
After I play around with this come more I’ll make another post with some more practical examples.
The Razor View Engine
Yesterday was the second MVCConf virtual conference. Since version 3 of the ASP.NET MVC framework was released last month, it was one of the more popular topics. Perhaps one of the most obvious additions to the framework is the Razor view engine.
One of the main design ideas behind the ASP.NET MVC framework is extensibility. To demonstrate this, you can have Visual Studio start a minimal ASP.NET MVC project that includes almost no code as opposed to the default project that includes some boilerplate controllers and such. However, you can also supply you own ORM, IoC container and testing framework. Another way to extend ASP.NET MVC is with view engines. The view engine that has been provided by default in the first two versions has been an adaption of WebForms using the .aspx extension. While version 3 also supports this view engine, a new view called Razor is the default.
Interestingly enough, Razor was not developed for ASP.NET MVC. It was developed for the ASP.NET WebMatrix (blog post on that soon). In fact, the engine was designed to have no dependencies on ASP.NET at all. It can be used in other project types as well.
The idea behind Razor is to permit code and markup to mix easier. The .aspx view engine requires explicit tags to mark the begin and end of code and markup. The Razor view engine tries to reduce the need for these extraneous tags and have the difference determined by the engine. Here is an example of Razor:
@{
var names = new string[] {"John", "Joseph", "James", "Jake"};
<ul>
@foreach(var name in names) {
<li>@name</li>
}
</ul>
}
There is a lot less markup needed to show where code blocks begin and end. In fact, tags are not used in that manner at all in Razor. The ‘@’ character is the beginning of a code block and Razor knows (most of the time) where the code block ends and the markup begins. The above code will render an unordered list with one list item for each of the items in the array.
We can also put comments in Razor views. To comment code, place the comment in between ‘@*’ and ‘*@’. In order to render a literal ‘@’, escape it with an ‘@’ like ‘@@’.
It is worth noting that the ‘@’ character auto HTML-encodes the content it renders by default which is something you had to do explicitly in .aspx views. If you need to disable this for content, use the @Html.Raw helper. Usually you will want to use this to render HTML passed into the page through the model. Otherwise, you will see the tags as text in the page.
An issue can come up when using Razor to help build filenames. Take the following code:
@ {
var profile = “myProfile”;
<a href=”@profile.html”>Profile Link</a>
}
What we are trying to do is render the name of the profile and append the ‘.html’ extension. This code will cause an error because it will think that .html is a property on @profile. We will get an error because strings have no property ‘html’. To fix this problem:
<a href=”@(profile).html”>Profile Link</a>
Surround the name of the object in parentheses.
That’s all for now. I’ll post more about Razor and how to use it in WebMatrix along with more of what I learned about MVC 3 during MVCConf later.
Schedule for MVCConf
Tomorrow is MVCConf! From 8-5 (US Central) in hour increments is going to be a virtual conference all about ASP.NET MVC. And it's free! I signed up a long time ago and have the whole day free for tomorrow. I'll be tweeting during the day and I'll do writeups of what I viewed soon. One problem is that I had to make some difficult choices because so much good content means I can't watch everything I want to see at once. Here is what I am planning to watch live tomorrow but fortunately all session will be recorded and archived for streaming later on. (all time US Central)
8:00 Evolving Practices in Using jQuery and Ajax in ASP.NET MVC Applications - Eric Sowell
9:00 BDD in ASP.NET MVC using SpecFlow, WatiN and WatiN Test Helpers - Brandon Satrom (this will likely be my first writeup)
10:00 Quality Driven Web Acceptance Testing - Amir Barylko
11:00 Keynote - Scott Guthrie
12:00 The NuGet-y Goodness of Delivering Packages - Phil Haack
1:00 MvcScaffolding - Steve Sanderson
2:00 Entity Framework "Code First": Domain Driven CRUD - Chris Zavaleta
3:00 MVC Q&A - Jeffrey Palermo (this was by far the toughest choice of all the slots)
4:00 Take some REST with WCF - Glenn Block
5:00 Conference Closing - Jon Galloway, Javier Lozano
Tommorrow is going to be a great day!
My First Complete GAE App
My first complete application with Google App Engine is up at:
http://quizservercreator.appspot.com
As the name implies, it is an application for creating and serving quizzes. It is written in Python and in somewhere around an alpha version. However, it is functional. The UI is minimal but it makes sense. The first glaring omission is that you can't see statistics and quizzes you have taken or created. Those statistics are being recorded but I just don't have a way to see them yet.
On the good side, several things do work. You can create quizzes and edit them which goes with out saying. There is a pretty neat interface for reordering the answers and the questions. However, the ordering is not stored yet. Also, to mark an answer as the correct one just click on it and it will turn green. Click on it again and it will turn red to indicate it is not correct. There is a box on the right side to remove an answer. Also, the UI will not let you submit a question without at least one answer marked correct. It is possible to submit an answer with more than one question but right now only the first one will be counted. On the home page it lists the most recent 4 quizzes created and will have some other categories too. The UI is only relevant to whether the user is logged in or not. When taking a quiz, there is nothing really special except that it is single page.
I'll keep working on this and writing about it. I am also thinking about a node.js version and an ASP.NET MVC version as well. Since it is so similar to GAE, the Tornado web server might be an interesting option because then I could use MongoDB or another database on EC2. There will also hopefully be some mobile clients as well and an HTML5 and Silverlight interface.
I'll probably start to open source this as I get more features and clean up the code.Tags: jQuery gae python
Goodbye 2010
I thought I would do one of these canonical, yet cliche, end of the year wrap up posts.
First off, the cool stuff ...
1) Windows Phone 7 - I got the Samsung Focus and I am very impressed. Outside of the battery issue I blogged about, I have not had a lot bad to say about it. I look forward to the copy and paste update early next year and the new HTML5 browser at the end of next year.
2) XBox Kinect - Well, Wii is no longer that cool. If you have a lot of space or don't mind rearranging the furniture a lot, this is worth it. Some people who don't like having a camera on them all the time might be a little weary but you don't notice it after a while.
3) iOS 4 - For Apple, it keeps getting better. iOS 3 made me take notice and 4 makes me want to use it. I updated my iPhone when it came out and after a few perfomance issues, have been pleased. The multi-tasking could be better but is welcome. Folders are something I use consistently.
4) iPad - This was slow to catch on with me. When I first touched one, the experience was neither magical nor revolutionary and I thought that $500 was a lot for an overgrown iPod touch. When the new one comes out next year, assuming it has the camera, I will get one.
5) Google TV - I know, there are a lot of people who are down on it. I haven't gotten one yet and won't until the SDK is released. I think that will open up the capabilities of the platform.
6) Android 2.3 (Gingerbread) - Speaking of Android, they finally got this one out.
7) HTML5 - Finally I have an excuse to give up on Flash/Flex! With mobile browsers and Microsoft getting on board, this should be usable in the next year.
The not so cool ...
1) MacBook Air -It's too expensive ... 'nuff said.
2) Google App Engine - I hate to say it, because it uses Python, but this was a complete disappointment. It's slow, it's unreliable and is hard to use and understand. (None of those are the fault of Python as Java is not better.)
3) Apple TV - Where are the apps? I thought this used iOS now?
4) Microsoft PDC - Non-event
But the best is saved for last ... the coolest award goes to ...
.NET 4 and Visual Studio 2010
Even though Microsoft is less than what they used to be, .NET and VS2010 give the best developer experience out there.
What am I looking forward to in 2011?
1) Finding a Ph.D. program in Management Science
2) XCode 4
3) Silverlight 5 (it still needs to run on the XBox guys!)
4) ASP.NET MVC 3
5) PyCon, CodeStock, DevLink (again!) and perhaps ... MIX?
One of my goals for 2011 is to blog and use social media to my advantage more. I think it will help me stay on track with my other goals if I announce them to the world. I will try to find a practical use for Facebook. I also want to start a podcast and do screencasting as well.