Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...

NAVIGATION - SEARCH

ASP.NET MVC 1.0 has been released!

ASP.NET MVC 1.0 QuicklyTo keep up with a good tradition (see here and here), I have some great news on ASP.NET MVC: we are at version 1.0! This means production ready, supported, stable, …! Grab the download at Microsoft.com.

I’m expecting an epic blog post by the Gu, but here’s some stuff you may want to have a look at: all my posts on ASP.NET MVC.

Another thing you can do: order my book on ASP.NET MVC :-) We’ve released the print version yesterday, meaning you are now completely set to start developing with ASP.NET MVC.

Edit: Looks like Simone was equally fast :-) And Kris.
Edit: More from MIX: Silverlight 3 SDK Beta 1 is already up! http://tinyurl.com/crfogs

kick it on DotNetKicks.com

CRUD with ASP.NET MVC (screencast)

A new screencast has just been uploaded to the MSDN Belgium Chopsticks page. Don't forget to rate the video!

CRUD with ASP.NET MVC (screencast)

Abstract: "In this video, the new tooling for Visual Studio included in ASP.NET MVC release candidate is demonstrated to create a create, read, update and delete user interface within 15 minutes."

kick it on DotNetKicks.com

Creating an ASP.NET MVC application with Google Gears

Offline web applications… This term really sounds like 2 different things: offline, no network, and web application, online. Maarten, you speak in riddles man! Let me explain the term…

You probably have been working with Gmail or Google Docs. One of the features with those web applications is that they provide an “offline mode”, which allows you to access your e-mail and documents locally, when an Internet connection is not available. When a connection is available, those items are synchronized between your PC and the application server. This offline functionality is built using JavaScript and a Google product called Google Gears.

In this blog post, I will be building a simple notebook application using the ASP.NET MVC framework, and afterwards make it available to be used offline.

What is this Gears-thingy?

According to the Google Gears website: Gears is an open source project that enables more powerful web applications, by adding new features to your web browser:

  • Let web applications interact naturally with your desktop
  • Store data locally in a fully-searchable database
  • Run JavaScript in the background to improve performance

Sounds like a good thing. I always wanted to make a web application that I could use offline, too. After reading the tutorial on Google Gears, I learned some things. Google Gears consists of an offline JavaScript extension framework, installed on your PC, together with a SQLite database. Second, there are some different components built on this client side installation:

  • Factory – An object which enables access to all of the following bullets.
  • Blob – Blob storage, the ability to store anything on the client PC.
  • Database – Yes, a database! Running on the local PC and supporting SQL syntax. Cool!
  • Desktop – Interaction with the client PC’s desktop: you can add a shortcut to your application to the desktop and start menu.
  • Geolocation – Locate the physical position of the client’s PC, based on either GPS, Wifi, GSM or IP address location.
  • HttpRequest – Can be used to simulate AJAX calls to the local client PC.
  • LocalServer – A local web server, which can be used to cache certain pages and make them available offline.
  • Timer – A timer.
  • WorkerPool – A class that can be used to execute asynchronous tasks. Think "threading for JavaScript".

Picking some components to work with…

Choices for Google Gears and ASP.NET MVC Have a look at the list of components for Google Gears I listed… Those are a lot of options! I can make an ASP.NET MVC notebook application, and make things available offline in several manners:

  • Read-only offline access: I can use the LocalServer to simply cache all rendered pages for my notes and display these cached pages locally.
  • Synchronized offline access: I can use the Database component of Google Gears to create a local database containing notes and which I can synchronize with the ASP.NET MVC web application.

Note: Also check the architecture page on Google Gears documentation. It covers some strategies on the latter option.

Choices… But which to choose? Let’s not decide yet and first build the “online only” version of the application.

Building the ASP.NET MVC application

Not too many details, the application is pretty straightforward. It’s a simple ASP.NET MVC web application built on top of a SQL Server database using LINQ to SQL. I’ve used a repository pattern to access this data using a defined interface, so I can easily mock my data context when writing tests (which I will NOT for this blog post, but you know you should).

The data model is easy: ASP.NET membership tables (aspnet_Users) linked to a table Note, containing title, body and timestamp of last change.

On the ASP.NET MVC side, I’ve used this repository pattern and LINQ to SQL generated classes using the Add view… menu a lot (check ScottGu’s post on this to see the magic…). Here’s a screenshot of the application:

image

Feel free to download the source code of the ASP.NET MVC – only application: GearsForMvcDemo - MVC only.zip (4.12 mb)

Next steps: deciding the road to follow and implementing it in the ASP.NET MVC application…

Adding Google Gears support (“go offline”) – Read-only offline access

Refer to the choices I listed: “I can use the LocalServer to simply cache all rendered pages for my notes and display these cached pages locally.” Let’s try this one!

The tutorial on Google Gears’ LocalServer states we need a manifest.json file, containing all info related to which pages should be made available offline. Great, but I don’t really want to maintain this. On top of that, offline access will need different files for each user since every user has different notes and so on. Let’s create some helper logic for that!

Autogenerating the manifest.json class

Let’s add a new Controller: the GearsController. We will generate a list of urls to cache in here and disguise it as a manifest.json file. Here’s the disguise (to be added in your route table):

[code:c#]

routes.MapRoute(
    "GearsManifest",
    "manifest.json",
    new { controller = "Gears", action = "Index" }
);

[/code]

And here’s (a real short snippet of) the controller, automatically adding a lot of URL’s that I want to be accessible offline. Make sure to download the example code (see further in this post) to view the complete GearsController class.

[code:c#]

List<object> urls = new List<object>();

// … add urls …

// Create manifest
return Json(new
{
    betaManifestVersion = 1,
    version = "GearsForMvcDemo_0_1_0",
    entries = urls
});

[/code]

The goodness of ASP.NET MVC! A manifest is built using JSON, and ASP.NET MVC plays along returning that from an object tree.

Going offline…

Next step: going offline! The tutorial I mentioned before contains some example files on how to do this. We need gears_init.js to set up the Google Gears environment. Check! We also need a JavaScript file setting up the local instance, caching data. Some development and… here it is: demo_offline.js.

This demo_offline.js script is built using jQuery and Google Gears code. Let’s step trough a small part, make sure to download the example code (see further in this post) to view the complete file contents.

[code:c#]

// Bootstrapper (page load)
$(function() {
    // Check for Google Gears. If it is not present,
    // remove the "Go offline" link.
    if (!window.google || !google.gears) {
        // Google Gears not present...
        $("#goOffline").hide();
    } else {
        // Initialize Google Gears
        if (google.gears.factory.hasPermission)
            initGears();

        // Offline cache available?
        if (!google.gears.factory.hasPermission || (store != null && !store.currentVersion)) {
            // Wire up Google Gears
            $("#goOffline").click(function(e) {
                // Create store
                initGears();
                createStore();

                // Prevent default behaviour
                e.preventDefault();
            });
        } else {
            // Check if we are online...
            checkOnline(function(isOnline) {
                if (isOnline) {
                    // Refresh data!
                    updateStore();
                } else {
                    // Make sure "Edit" and "Create" are disabled
                    $("a").each(function(index, item) {
                        if ($(item).text() == "Edit" || $(item).text() == "Create New") {
                            $(item).attr('disabled', true);
                            $(item).click(function(e) {
                                e.preventDefault();
                            });
                        }
                    });
                }
            });

            // Provide "Clear cache" function
            $("#goOffline").text("Clear offline cache...").click(function(e) {
                // Remove store
                removeStore();
                window.location.reload();

                // Prevent default behaviour
                e.preventDefault();
            });
        }
    }
});

[/code]

What we are doing here is checking if Google gears has permisison to store data from this site on the local PC. If so, it is initialized. Next, we check if we already have something cached. If not, we wire up some code for the “Go offline” link, which will trigger the creation of a local cache on click. If we already have a cache, let’s do things different…

First, we call a simple method on the GearsController class (abstarcted in the checkOnline JavaScript function), checking if we can reach the server. If so, we assume we are online and ask Google Gears to check for updated contents. We always want the latest notes available! However, if this function says we are offline, we look for al links stating “Edit” or “Create New” on the current page and disable them. Read-only we said, so we are not caching “Edit” pages anyway. This is just cosmetics to make sure users will not see browser errors when clicking “Edit”.

 Going offline!

Conlusion for this approach

This approach is quite easy. It’s actually instructing Google Gears to cache some stuff periodically, backed up by an “is online” checker in the ASP.NET MVC application. This approach does feel cheap… I’m just creating local copies of all my rendered pages, probably consuming too much disk space and probably putting too much load on the server in the update checks.

Want to download and play? Here it is: GearsForMvcDemo - Offline copy.zip (4.11 mb)

Adding Google Gears support (“go offline”) – Synchronized offline access

In the first approach, I concluded that I was consuming too much resources, both on client and server, to check for updates. Not good! Let’s try the second approach: “I can use the Database component of Google Gears to create a local database containing notes and which I can synchronize with the ASP.NET MVC web application.”

What needs to be done:

  • Keep the approach described above: we will still have to download some files to the local client PC. The UI will have to be available. Not that we will have to download all note details pages, but we want the UI to be available locally.
  • Add some more JavaScript: we should be able to access all data using JSON (as an extra alternative to just providing web-based views that the user can work with).
  • The above JavaScript should be extended: we need offline copies of that data, preferably stored in the Google Gears local database.
  • And yet: more JavaScript: a synchronization should occur between the local database and the data on the application server.

Ideally, this should look like the following, having a JavaScript based data layer available:

Google Gears Reference Architecture

Due to a lack of time, I will not be implementing this version currently. But hey, here's a nice blog post that should help you with this option: .NET on Gears: A Tutorial

Conlusion for this approach

The concept of this approach is still easy, but requires you to write a lot of JavaScript. However, due to the fact that you are only synchronizing some basic UI stuff and JSON data, local and server resources are utilized far less than in the first approach I took.

Conclusion

The concept of Google Gears is great! But I seriously think this kind of stuff should be available in EVERY browser, natively, and with the same API across different browsers. Storing data locally may bring more speed to your application, due to more advanced caching of UI elements as well as data. The fact that it also enables you to access your application offline makes it ideal for building web applications where connectivity is not always guaranteed. Think mobile workers, sales people, ..., all traveling with a local web application. Not to forget: Gears is currently also available for Windows Mobile 5 and 6, which means that ultra-mobile people can run your web application offline on their handheld device! No need for specific software for them!

By the way, also check this: .NET on Gears: A Tutorial. Interested in Silverlight on Gears? It has been done!

kick it on DotNetKicks.com

Announcing my book: ASP.NET MVC 1.0 Quickly

ASP.NET MVC 1.0 Quickly It’s been quite a job, but there it is: Packt just announced my very first book on their site. It is titled “ASP.NET MVC 1.0 Quickly”, covering all aspects ASP.NET MVC offers in a to-the-point manner with hands-on examples. The book walks through the main concepts of the MVC framework to help existing ASP.NET developers to move on to a higher level. It includes clear instructions and lots of code examples. It takes a simple approach, thereby allowing you to work with all facets of web application development. Some keywords: Model-view-controller, ASP.NET MVC architecture and components, unit testing, mocking, AJAX using MS Ajax and jQuery, reference application and resources.

That’s it for the marketing part: let’s do a retrospective on the writing process itself. Oh and yes, those are my glasses on the cover. Photo was taken on the beach near Bray-Dunes (France).

When did you have the idea of writing a book?

I'm not sure about that. I've been blogging a lot on ASP.NET MVC last year, wrote an article for .NET magazine, did some presentations, ... It occurred to me that I had a lot of material which I could bundle. Together with that, my project manager jokingly said something like: "When will you write your first book? With all that blogging." So I did start bundling stories. First of all, I overlooked the whole ASP.NET MVC technology (preview 2 at that moment) and decided there were enough topics to talk about. A draft table of contents was built quite quick, but I gave up on writing. Too much information, not enough time, ...

A few weeks later, it must have been around the beginning of May, 2008, I did start writing a first chapter, thinking I'ld see how the writing itself would turn out, if it fit in my schedule, ... It worked out quite well, each 10-20 days gave me a new chapter. I also started looking for a publisher when I was finished with chapter 6 or so. Having reviewed some books for Packt, I contacted them with a proposal for my book.

After having a look at the other 6 upcoming books (here and here), we decided we could go for it, focusing on a hands-on book which rapidly guides you into the wonderful world of ASP.NET MVC.

How was your experience of writing your book?

Looking back, it was an interesting experience. I decided to write in English, which is not my native language. That was actually quite a hard one: writing in English is no problem, but writing a good, solid and interesting piece of text is just not that easy when writing longer texts than the average blog post. Another thing is that I tortured myself writing about a product that was not even beta yet! I started writing with ASP.NET MVC preview 3, updated it all to preview 4, 5, beta, release candidate, ... Lots of changes in the ASP.NET MVC API or concepts meant lots of changes to make in chapters I already wrote. Luckily, I survived :-)

I only contacted a publisher when I had finished 60% of my book. If you are considering writing: don't do this! Contact a publisher at a very early stage: they normally give you lots of advice upfront, which I only received after contacting them. Advice earlier along the way is always better, so that's something I would definately do different.

Speaking of advice: when writing was done, the book entered review phase. Different people received the draft version and could provide comments and suggestions. Thanks Stefan, Troy, Vivek, Jerry, Joydip and people at Packt for your time in reviewing my draft version! Reviewer comments really made the book better and required me to do some small rewrites, elaborate more on certain topics.

What tools did you use for writing?

There are some tools that you really need when writing a technical book. One of them is a text editor, in my case Microsoft Word 2007. Together with that, Visual Studio 2008 and regularly updated ASP.NET MVC versions were required. Being scared of losing data, I decided to also use a source control system for sample code ánd for my Word documents. All of these files were stored in a Subversion repository located on my server, being backed up every day to different locations. Doug Mahugh laughed at me when I said I was using Subversion, but it did a great job!

Other tools I used were Paint.NET and MwSnap, both for creating screenshots in my virtual PC running Windows Vista and Visual Studio 2008. I also used Achievo for time tracking purposes, since I was curious how much time this book writing would actually cost me.

How much time did you spend writing?

First of all, this is not going to be 100% accurate. I did track writing and development time during writing, but I already had a lot of material to work with. But here's an overview (numbers in hours):

image

That is right: writing a book consumes only a little more than 100 hours! But still, I already had lots of material. I'd say to double the number for an accurate timeframe.

Now I hear the next question coming... Here's the answer already: Yes, I have a girlfriend. We are working on our home (planning phase is done, searching a contractor at the moment), visiting family, doing daily stuff, blogging, work, ... It al worked out to fit together, but still: there have been some busy moments on evenings and weekends. Thanks, people around me, for being patient and caring during these busy moments!

Are you getting rich out of this?

Of course, I can grab a couple of beers (for a couple of times), but don't think writing a book will buy you a car... I just felt that I had lots of valuable information that I had to share, and writing a book seemed like the best option to do that. Creating a "to read"-list? Make sure to add ASP.NET MVC 1.0 Quickly to it.

kick it on DotNetKicks.com

Form validation with ASP.NET MVC release candidate

Last week, the ASP.NET MVC framework release candidate was released (check ScottGu’s post). Apart from some great new tooling support, form validation has never been easier. Here’s a quick introduction.

Employee from Northwind database Imagine we have a LINQ to SQL data model, containing an Employee from the Northwind database. As you may know, LINQ to SQL will generate this Employee class as a partial class, which we can use to extend this domain object’s behaviour. Let’s extend this class with an interface implementation for IDataErrorInfo.

[code:c#]

public partial class Employee : IDataErrorInfo
{
    #region IDataErrorInfo Members

    public string Error
    {
        get { throw new NotImplementedException(); }
    }

    public string this[string columnName]
    {
        get { throw new NotImplementedException(); }
    }

    #endregion
}

[/code]

IDataErrorInfo is an interface definition that is found in System.ComponentModel. It provides the functionality to offer custom error information that a user interface can bind to. Great, let’s do that! Assume we have a view which is used to edit this Employee object. The code for this will be quite easy: some HTML form stuff, Html.ValidationMessage calls, … Here’s a snippet:

[code:c#]

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Edit</h2>

    <%= Html.ValidationSummary() %>

    <% using (Html.BeginForm()) {%>
        <%= Html.Hidden("id", Model.EmployeeID) %>

        <fieldset>
            <legend>Fields</legend>
            <p>
                <label for="LastName">LastName:</label>
                <%= Html.TextBox("LastName") %>
                <%= Html.ValidationMessage("LastName", "*") %>
            </p>

            <!-- ... -->

        <fieldset>
    <% } %>

</asp:Content>

[/code]

The controller’s action method for this will look like the following:

[code:c#]

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)

    Employee employee = repository.RetrieveById(id);

    try
    {
        UpdateModel(employee, collection.ToValueProvider());
        repository.Save(employee);

        return RedirectToAction("Index");
    }
    catch
    {
        return View(employee);
    }
}

[/code]

Nothing fancy here: a call to UpdateModel (to populate the Employee instance with data fom the form) and a try-catch construction. How will this thing know what’s wrong? This is where the IDataErrorInfo interface comes useful. ASP.NET MVC’s UpdateModel method will look for this interface implementation and retrieve information from it. The Error property that is defined on IDataErrorInfo returns a string containing any error that is “global” for the Employee object. The this[string columnName] indexer that is defined on IDataErrorInfo is used to retrieve error messages for a specific property. Now let’s make sure FirstName and LastName are provided:

[code:c#]

public partial class Employee : IDataErrorInfo
{
    #region IDataErrorInfo Members

    public string Error
    {
        get { return ""; }
    }

    public string this[string columnName]
    {
        get
        {
            switch (columnName.ToUpperInvariant())
            {
                case "FIRSTNAME":
                    if (string.IsNullOrEmpty(FirstName))
                        return "Please provide a firstname.";
                    break;
                case "LASTNAME":
                    if (string.IsNullOrEmpty(LastName))
                        return "Please provide a lastname.";
                    break;
            }

            return "";
        }
    }

    #endregion
}

[/code]

Great, let’s try it out. If I omit the firstname or lastname when editing an Employee object, here’s what the view looks like:

ASP.NET MVC form validation

How easy was that! More on the new things in the ASP.NET MVC release candidate can be found in ScottGu’s blog post.

kick it on DotNetKicks.com

Updated CarTrackr to ASP.NET MVC RC

image As you may have noticed, ASP.NET MVC 1.0 Release Candidate has been released over the night. You can read all about it in ScottGu’s blog post, covering all new tools that have been released with the RC.

Since I’ve been trying to maintain a small reference application for ASP.NET MVC known as CarTrackr, I have updated the source code to reflect some changes in the ASP.NET MVC RC. You can download it directly from the CodePlex project page at www.cartrackr.net.

Here’s what I have updated (copied from the release notes):

Specifying View Types in Page Directives

The templates for ViewPage, ViewMasterPage, and ViewUserControl (and derived types) now support language-specific generic syntax in the main directive’s Inherits attribute. For example, you can specify the following type in the @ Master directive:

[code:xml]

<%@ Master Inherits="ViewMasterPage<IMasterInfo>" %>

[/code]

An alternative approach is to add markup like the following to your page (or to the content area for a content page), although doing so should never be necessary.

[code:xml]

<mvc:ViewType runat="server" TypeName="ViewUserControl<ProductInfo>" />

[/code]

The default MVC project templates for Visual Basic and C# views have been updated to incorporate this change to the Inherits attribute. All existing views will still work. If you choose not to use the new syntax, you can still use the earlier syntax in code.

ASP.NET Compiler Post-Build Step

Currently, errors within a view file are not detected until run time. To let you detect these errors at compile time, ASP.NET MVC projects now include an MvcBuildViews property, which is disabled by default. To enable this property, open the project file and set the MvcBuildViews property to true, as shown in the following example:

[code:xml]

<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
  <PropertyGroup> 
    <MvcBuildViews>true</MvcBuildViews> 
  </PropertyGroup>

[/code]

Note: Enabling this feature adds some overhead to the build time.

You can update projects that were created with previous releases of MVC to include build-time validation of views by performing the following steps:

1. Open the project file in a text editor.

2. Add the following element under the top-most <PropertyGroup> element:

[code:xml]

<MvcBuildViews>true</MvcBuildViews>

[/code]

3. At the end of the project file, uncomment the <Target Name="AfterBuild"> element and modify it to match the following example:

[code:xml]

<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'"> 
    <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
</Target>

[/code]

kick it on DotNetKicks.com

Book review: ASP.NET 3.5 Social Networking

image Last week, I found another book from Packt in my letterbox. This time, the title is ASP.NET 3.5 Social Networking, written by Andrew Siemer.

On the back cover, I read that this book shows you how to create a scalable, maintainable social network that can support hundreds of thousands of users, multimedia features and stuff like that. The words scalable and maintainable seem to have triggered me: I started reading ASAP. The first chapter talks about what a social network is and proposes a new social network: Fisharoo.com, a web site for salt water aquarium fanatics, complete with blogs, forums, personal web sites, …

The book starts by building a framework containing several features such as logging, mail sending, …, all backed-up by a dependency injection framework to enable fast replacement of several components. Afterwards, each feature of the Fisharoo.com site is described in a separate chapter: what is the feature, how will we store data, what do we need to do in our application to make it work?

A good thing about this book is that it demonstrates several concepts in application design using a sample application that anyone who has used a site like Facebook is familiar with. The concepts demonstrated are some that any application can benefit from: Domain Driven Design, Test Driven Design (TDD), Dependency Injection, Model-View-Presenter, … Next to this, some third-party components like Lucene.NET are demonstrated. This all is very readable and understandable, really a must-read for anyone interested in these concepts!

Bottom line of the story: it has been a while since I was enthousiast about a book, and this one clearly made me enthousiast. Sure, it describes stuff about building a social network, but I think that is only a cover for what this book is really about: building good software that is easy to maintain, test and extend.

Checking username availability with jQuery (screencast)

A new screencast has just been uploaded to the MSDN Belgium Chopsticks page. Don't forget to rate the video!

Checking username availability with jQuery

Abstract: "This screencast explains how to use jQuery and the ASP.NET MVC framework to quickly add a username availability checker to a user registration page."

kick it on DotNetKicks.com

Book review: ASP.NET 3.5 Application Architecture and Design

image The people at Packt asked it again: “Do you want to review this book?” Sure I do! The book I’m reviewing this time is ASP.NET 3.5 Application Architecture and Design, written by Vivek Thakur.

Application Architecture is always an interesting topic to read on. Different people have different opinions, there is no one perfect solution to a problem, … This book covers application architecture, applied to ASP.NET, although these concepts can be applied in any application. Questions like “What are tiers?” and “How do you structure an application?” are dug into in the first few chapters. The next chapters focus on more specific areas of application architecture: the domain model, UML, creating an ER diagram, SOA, the ASP.NET MVC framework, … Each of these concepts is explained using a single project example, which makes it easy to see the differences, pro’s and con’s of a certain solution.

To be honest, I don’t think this book is something for experienced architects or lead developers. More experienced architects will probably remain a little bit hungry because large, complex, real-world architectures are not covered or illustrated. The book covers all concepts of application architecture using a simple example, which makes them clear to any developer who is interested in architecture but has always been affraid of all these concepts.

If you are familiar with the words “N-Tier”, “domain model” and other architectural concepts, I think this book might not be covering architecture deep enough. Are you a developer wanting to release some open-source software? Unaware of the concepts mentioned? Then read this book as it is a great starter book.

CarTrackr on Windows Azure - Part 5 - Deploying in the cloud

This post is part 5 (and the final part) of my series on Windows Azure, in which I'll try to convert my ASP.NET MVC application into a cloud application. The current post is all about deploying CarTrackr in the cloud after all modifications done in previous posts.

Other parts:

Deploying CarTrackr on Azure

Deploying CarTrackr is done using the Azure developer portal. I'm creating a hosted service named "CarTrackr", which will host the cloud version of CarTrackr. I'm also creating a second storage acocunt project, used for TableStorage of all data in CarTrackr.

CarTrackr projects on Azure

To create a deployment package, the documentation states to right-click the Azure project in the CarTrackr solution, selecting "Publish...". I really hoped this would be easy. Unfortunately, this was some sort of a PITA... Great to see an Exception in the output window. Fortunately, someone had the same issue: Packaging Azure project manually when the 'Publish' action fails. The Exception seems to be thrown because the CarTrackr project is too big for the packaging system. *sigh* Starting an Azure SDK command-line and invoking the cspack.exe seemed to do the trick.

Anyway, on to uploading the generated package to Azure: the package, service configuration and deployment name should be given, after which an upload takes place.

Azure Services Developer Portal

Time to run! After browsing to http://cartrackr.cloudapp.net, I'm expecting to see CarTrackr!

CarTrackr running... NOT!

But no, Error 403 - Forbidden - Access is denied... What is wrong? My quest to host CarTrackr on Azure seems to be full of obstacles...

Deploying again!

After some hours of re-packing, re-building, re-deploying and starting to get annoyed, the solution was to change my call to cspack.exe... Not only the /bin folder should be packaged, but also all other content. My bad! Invoking C:\Users\Maarten\Desktop\CarTrackr>cspack "./CarTrackr_Azure/ServiceDefinition.csdef" /out:"./CarTrackr_Azure/CarTrackr_Azure.cspkg" /role:"Web;./CarTrackr"  was the right thing to do.

A deployment later, CarTrackr seemed to work smoothly!

CarTrackr on Azure!

And again...

Yes, again. I wrote this blog post about a week ago and decided to add Google Analytics in the live version of CarTrackr. While deploying, I decided to upload the latest version to the staging environment, and swap it with the production environment... Bad idea :-) Deployment totally killed my data storage (it seemed) and was throwing strange errors on the production URL.

Some hours later (that is: 2 hours of build, deploy, check, ..., a night sleep and some more build, deploy, check, ...), I had the strange idea of putting my production ServiceConfiguration data in the package itself. This should not be necessary, but you never know. And it is what I did with the first working production deployment. And yes, this indeed seemed to be the solution!

Check it out!

Checkout http://cartrackr.cloudapp.net for the live version. No need to sign up, only to sign in. Note: when entering a refuelling, enter the date in US English format... 

It is likely that you are going to download and play with my source code. When doing that, check out the TableStorage membership, role and session providers in the Azure SDK, which you can use in CarTrackr if you want. More on this can be found on http://blogs.msdn.com/jnak/archive/2008/11/10/asp-net-mvc-on-windows-azure-with-providers.aspx.

Looking for the Azure CarTrackr sources? CarTrackr_Azure.zip (654.98 kb)
Looking for the original CarTrackr sources? Checkout CodePlex.

Conclusion on Azure

It took me quite some hours to actually convert an existing application into something that was ready for deployment on Azure. The toughest parts were rewriting my repository code for TableStorage and getting the CarTrackr package deployed. With what I know know, I think writing an Azure application should not be more difficult than writing any other web application. The SDK provides everything you need, remember to check the samples directory for some useful portions of code.

I do have some notes though, which I hope will be used for future CTP's of Azure...

  • Your application is running fine on the development fabric?
    There's no 100% guarantee that the Azure web fabric will serve your application correctly when it runs smoothly on the development fabric. Just deploy and pray :-)
  • Viewing log files from the web fabric from the Azure Services Developer Portal would be a real time saver!
    Currently, you can copy the server logs to blob storage and then fetch the data from there, but a handy web-tool would really save some time when something goes wrong after deployment. Same story goes for TableStorage: it would be useful to have an interface to look at your data.
  • Packaging? Great, but... what if I only wanted to update one file in the application?
    I've uploaded my package about 10 times during deployment testing, which required 10 times... the full package size in bandwith! And all I wanted to do was modifying web.config...

Sidenote: funny to see that they are using OPC (Open Packaging Convention) for creating deployment packages. It shows how easy it is to create a custom file format with OPC, just like Julien Chable did for a photo viewer.

Overall, Microsoft is doing a good job with Azure. The platform itself seems reliable and stable, the concept is good. Perhaps they should consider selling the hosting platform itself to hosting firms around the globe, setting a standard for hosting platforms. Think of switching your hosting provider by simply uploading the package to another company's web fabric and modifying some simple configuration entries. Another idea: why not allow the packages developed for Azure to be deployed on any IIS server farm? 

kick it on DotNetKicks.com