Sunday, 30 August 2009

MonoTouch Settings.bundle

Property Lists (plist) and Bundles are probably so obvious to seasoned Mac/iPhone developers that they're not even worth mentioning, however for someone with a '100% .NET' background you can't take anything for granted. I had a -lot-bit of trouble getting iPhone Settings working with MonoTouch (see here), but now that I've figured it out it seems very simple. Here's a quick guide:

1. Bundles are folders
Within your MonoTouch project, create a new folder (right-click solution → Add → New Folder) and call it Settings.bundle


2. Plist files are some sort of hybrid Xml key-value
(right-click solution → Add → New File... → Empty Text File) and call it Root.plist. You could add an existing plist-xml-formatted file if you like - but we're just going to create one from scratch (in the next step).


3. Edit Root.plist with the Property List Editor
The structure of the plist is very specific - look for some doco or Chapter 10 of Beginning iPhone Development. In this example I've only used PSGroupSpecifier and PSTextFieldSpecifier but there are many other types (PSMultiValueSpecifier, PSToggleSwitchSpecifier, PSChildPaneSpecifier...).
Double-click the Root.plist file inside MonoDevelop to open the Property List Editor - type carefully as there is no 'validation' and if you mis-spell (or mis-capitalize) something it just won't work:


4. Set the correct build action for Root.plist
This is important (and I think the cause of my earlier problem) - you MUST tell the IDE to make sure this file is copied to the phone.


5. Access the settings
Use the NSUserDefaults.StandardUserDefaults property to access the values set by the user.


6. See/Edit "Settings" on the iPhone


It's worthwhile noting that the 'useability' for these kinds of Settings is 'unusual' for desktop applications, but probably familiar to iPhone users... the settings for a whole swag of unrelated applications are grouped under the Settings icon (it's not necessarily obvious from with the application that they are available). The user must also quit the application to get to these settings - which means they're most useful for things that don't change much (eg. the users identity and servers in the Mail.app).

Thursday, 27 August 2009

MonoTouch "iSOFlair"

UPDATE: 6-Oct version 2.0 adds some functionality and the source code.

I didn't get as far as I'd have liked with today's MonoTouch app - a pretty basic rendering of your 'score' on stackoverflow.com (via their 'flair' feature). Yep, definitely not a 'practical' application.

The main goals were to play with WebClient, the 'filesystem' and then to get a multi-page/view app working with proper Settings (to configure the various stackoverflow variants). As you can see from the screenshots below I only got half-way there...


Here's the code: Main.cs, MainWindow.xib.designer.cs and root.plist. At least the WebClient for text and images worked well, as did saving and loading from the local file system. You'll have to excuse the dodgy Html parsing ;)

Unfortunately I've wasted a bit of time trying to figure out the Settings and how to get the plist setup correctly. I first created a folder in MonoDevelop called Settings.bundle with the root.plist inside. It has to be "partly" correct because the application now appears in the Settings menu - which it wasn't before - BUT when you select it the screen is empty of inputs :-(
I'm probably missing something really basic - the root.plist file is shown in the editor below:

Anyway, I'll do some more reading and try again tomorrow!

Obligatory Interface Builder screenshot...

Wednesday, 26 August 2009

MonoTouch "Restaurant Bill Splitter"

Okay - my first "real" iPhone via MonoTouch beta application is complete... welcome to Restaurant Bill Splitter, the easiest way to determine who pays the check :-)

Here it is before any data entry and after you have entered the total restaurant bill (plus the subtotal of any alcohol in that figure) and chosen the number of drinkers versus non-drinkers who are going to pay.



Here is the Interface Builder screen shot


You can also download the MonoTouch BillSplitter solution (11Kb) and view the c# code for Main.cs and MainWindow.xib.designer.cs. Even though MonoTouch is currently still in (closed) beta, it is VERY cool to be able to write c#/.NET targetting the iPhone platform. There is still quite a bit to get my head around (mostly the Apple stuff: XIBs, Views, delegates, events, Interface Builder, etc) but hopefully once I get the hang of it, much more complex applications will be forthcoming...

NOTE: there is one known bug in there... I'm having trouble making the keyboard disappear when you press the [Done] button - so if you're wondering what all the ResignFirstResponder() delegates are for, it's my attempt to debug/fix the keyboard problem. That is also the reason for the [Split] button, which otherwise wouldn't really be required since the calculations happen 'on change' for each of the input controls...


UPDATE: this is the class diagram for the app (obviously excludes stuff *in* the XIB, but includes the .xib.designer.cs). I've also posted the class diagrams for Foundation and UIKit online.

Tuesday, 25 August 2009

MonoTouch "Hello World"

First, let me say that this is the MonoTouch team's "Hello World" code. I'm still trying to figure this whole MonoTouch thing out, so I've given @redth's YouTube screencast a try, and posted my own screenshots (even though they look a lot like these)...

Massive thanks for @redth for the screencast - hopefully I'll be posting something of my own creation very soon. It made a lot more sense (more quickly) than reading.

Anyway, here's the quick links:

0. Read "Hello World" on the MonoTouch official site

1. Watch @redth's screencast

2. Check out my screenshots
Here are a couple of them...


Wednesday, 19 August 2009

Parsing XML with PHP4

PHP is not something I'm familiar with, but I was recently helping out a friend and was surprised how difficult it was to find some sample code for downloading/parsing an XML (specifically using PHP4, apparently PHP5 has some built-in functionality).

Thankfully I stumbled across Taha Paksu's SimpleXML for PHP4 - you must join/login to download it, but it's worth it.

Once you have downloaded the ZIP file, place simplexml.class.php in your PHP 'app', and use the supplied example test.php to ensure everything is working:
<?
require_once "simplexml.class.php";

echo "<pre>";
$file = "http://musicbrainz.org/ws/1/track/?query=metallica&type=xml";
$sxml = new simplexml;
$data = $sxml->xml_load_file($file);
print_r($data);
?>
which prints out a 'tree view' of the XML data.

If that works, you can then address individual elements (say your XML looks like this - an example from the download)
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>
<format>text</format>
<content>Don't forget me this weekend!</content>
</body>
</note>
then your PHP might look like this:
<?
require_once "simplexml.class.php";

$file = "http://SOMESERVER.com/example.xml";
$sxml = new simplexml;
$data = $sxml->xml_load_file($file);
?>
<html>
<body>
<table>
<td>to:</td><td><?php echo $data->to; ?></td>
<td>sender:</td><td><?php echo $data->from; ?></td>
<td>subject:</td><td><?php echo $data->heading; ?></td>
<td>message:</td><td><?php echo $data->body->content; ?></td>
</table>
</body>
</html>


You can read more in the SimpleXML for PHP4 forum... That's enough PHP for now - back to c#/t-sql/xaml/html/javascript... and hopefully soon MonoTouch!

Friday, 14 August 2009

When Mono "just works" - Searcharoo 'ported'

Decided to have another play with Mono today, in preparation for MonoTouch to come out of beta (or for my beta-participation to be approved)...

It was very easy to install Mono and MonoDevelop on my Mac, and because MonoDevelop supports Visual Studio 2008 solution files the current release of Searcharoo opened straight away*, compiled and could be tested with the 'provided' XSP2 webserver:


* I removed the Silverlight project from the Searcharoo solution (playing with Moonlight is a project for another day), but the Silverlight XAP from my Windows machine runs happily on the Mac against the Mono-version of the website:


The other cool thing about MonoDevelop is that it already supports the iPhone/MonoTouch 'project types'. You can't compile/test/run anything (you need MonoTouch.Foundation and MonoTouch.UIKit which are in 'private beta'), but you can browse the MonoTouch Samples - so at least you can see what C# code for the iPhone looks like. Fingers crossed Miguel and the team release the bits publicly ASAP :-)

Wednesday, 12 August 2009

City2Surf 2009 on RaceReplay.net with Flickr

The world's "largest timed footrace" - Sydney's City2Surf - is now viewable on RaceReplay.net thanks to Silverlight and BingMaps.

There are two 'new' features:

1) Flickr photo integration (try it)

Using the Flickr photo search API, the Silverlight client renders small pink-and-blue dots for photos that are both geo-tagged and tagged:"city2surf". Clicking on the dot will open the Flickr page.



2) Visualizing the entire race (try it)

It is (unfortunately) impossible to animate the 65,000 or so points that would represent every runner and walker taking part in the event. By aggregating the finishers into timebands (and using both size & opacity to represent 'value') you can get some idea of the distribution of participants over time, over the course.



Add yourself!

As always, you can search for and add more 'runners' to the animation. Start typing a name into the autocomplete box, select from the list (optionally choose a color from the color-picker) and click Add runner.

Friday, 31 July 2009

Seadragon - Deep Zoom on Demand

Microsoft LiveLabs just announced the release of Seadragon.com, an Azure-based service that creates hosted DeepZoom images 'on demand', making it super-easy to share very-high-resolution images with a quick link.

I tried it out with a few images from my Flickr account (they only take a minute or two to 'process')... click the links to play with Seadragon, click the images just to see a larger copy

Sydney skyline 9774 x 2154 (21 megapixels)



Seattle suburbs from the Space Needle 11991 x 2186 (26 megapixels)



Here's a few more to try for yourself:

Sydney at night 2048 x 768 (1.6 megapixels)

Pike Place Farmers Market 5273 x 2309 (12 megapixels)

Space Needle and Mt Rainier 6388 x 2366 (15 megapixels)

Seattle waterfront from the Space Needle 8861 x 2062 (18 megapixels)

Pike Place close-up 11323 x 3026 (34 megapixels)

As LiveLabs mentions on their website - an easy way to add hi-res images to your eBay listing, real-estate website, ecommerce store, blog, etc...

Saturday, 11 July 2009

SQL in Silverlight

It never ceases to amaze me how short my attention span has become...

what was I saying :) ?

Aaanyway, I sat down in front of my PC today planning to accomplish a few different things... but before that I had to catch up on blogs and twitter. A tweet caught my eye
migueldeicaza IDEA: SOmeone to do a line-by-line port of Sqlite to C# to run inside Silverlight

"Great idea" I thought... but seemed like quite a big job and certainly not something I have the time to tackle. Then I started to recall seeing a C# port of an SQL engine (ages ago) and thought it might be fun to have a poke around. At least it would be easier to port something already in .NET land.

A couple of Google results later, I came across Sharp HSql, a circa 2001 port of the Java-based hsqldb (licence). The code was subsequently added to Codeplex with the following warning: This version is not ready for production grade applications. More testing is needed and some important bugs has to be fixed before that. You are warned.
Long story short...
it's a couple of hours later and I've done nothing that I'd planned to, but here is an 'alpha' of SharpHSql for Silverlight (try it out) - there's some test SQL at the bottom of the post.


The "port" mainly consisted of:
  • 'implementing' ArrayList and Hashtable (umm, can you say List<object> and Dictionary<object, object>)
  • removing the 'Provider' and all the dependencies on System.Data that work fine in the full framework, but are missing from Silverlight (would be nice to add some sort of wrapper back in...)
  • converting FileInfo and related operations to IsolatedStorageFileStream (still some persistence testing to do...)
  • breaking DateTime handling (for now)
The REAL work was all done by Mark Tutt so don't get the idea that I'm taking any credit - all the goodness is his, any errors are mine.

The full source of the consuming Silverlight app is this Page.xaml and Page.xaml.cs; the full Visual Studio 2008 project ZIP (199Kb) is available to download. Anywhere I've touched the code you'll find a //HACK: tag!

Disclaimer: I've no idea if this is fit for any purpose at all... it seems to be able to DROP and CREATE tables, INSERT rows and SELECT/JOIN - but even that could be a fluke. Try it out at your own risk; leave a comment if you find something good or bad. Have fun!

UPDATE: the output is a lot prettier (try it) with the Silverlight DataGrid and Vladimir Bodurov's awesome dynamic datasource compiler - updated for generic types

(updated source (277Kb))

Test SQL

#1
DROP TABLE IF EXIST "books";CREATE TABLE "books" ("id" INT NOT NULL PRIMARY KEY, "name" char, "author" char, "qty" int, "value" numeric);

INSERT INTO "books" VALUES (1, 'Book000', 'Amy', 1, 23.5);
INSERT INTO "books" VALUES (2, 'Book001', 'Andy', 2, 43.9);
INSERT INTO "books" VALUES (3, 'Book002', 'Andy', 3, 37.25);
INSERT INTO "books" VALUES (4, 'Book 21', 'Amy', 99, 20.5);
INSERT INTO "books" VALUES (5, 'Book 22', 'Andy', 2, 903.9);
INSERT INTO "books" VALUES (6, 'Book 23', 'Andy', 5, 0.25);

SELECT * FROM "books" ORDER BY "value"

DROP TABLE IF EXIST "author";CREATE TABLE "author" ("name" char NOT NULL PRIMARY KEY, "country" char);

INSERT INTO "Author" VALUES ('Andy', 'UK');
INSERT INTO "Author" VALUES ('Amy', 'USA');

SELECT * FROM "author" ORDER BY "value"

SELECT * FROM "books" LEFT JOIN "author" ON "author"."name" = "books"."name"
#2
CREATE TABLE "clients" ("id" int NOT NULL IDENTITY PRIMARY KEY, "DoubleValue" double, "nombre" char, "photo" varbinary, "created" date );
INSERT INTO "clients" ("DoubleValue", "nombre", "photo", "created") VALUES (1.1, 'NOMBRE')
SELECT * FROM "clients"

Friday, 10 July 2009

Silverlight 3.0 - can't upgrade Runtime without DevTools?

Silverlight 3.0 has been RTW (Released To Web), so I rushed straight to Silverlight.net to install it. Because I'm a Silverlight developer, I already have Silverlight 2.0 and the Silverlight 2.0 Tools for Visual Studio installed (of course).

Silverlight.net immediately notices I'm "out of date" and suggests I install the latest version.


After the quick 4Mb download, the installation seems to be going well...


...until... oops, I can't upgrade the Runtime in browser if the Visual Studio developer tools are out-of-date (ie. for 2.0)??


I'll just click 'more information' to read more - oh wait, 404


At the moment it seems like you'll have to install the full Silverlight 3.0 Developer Tools just to view Silverlight 3.0 content (if you were previously developing for Silverlight 2.0).

Only problem is, Silverlight 3 Release Notes says
Silverlight 2 projects cannot be created with the Silverlight 3 Tools for Visual Studio 2008. To create Silveright 2 projects, uninstall the Silverlight 3 runtime and the Silverlight 3 Tools from Add or Remove Programs and re-install the Silverlight 2 Tools for Visual Studio 2008.
I'm not sure I want to force all my users to upgrade to Silverlight 3.0 right now - I don't wany my website to be the one that forces a 4Mb download until I really need it (ie. I start using 3.0 features). So... to keep developing on 2.0 (for now), I can't even view Silverlight 3.0 content?

Please - tell me I'm wrong and that I've missed something?

UPDATE: Thankfully, in a VirtualPC set aside for SL3.0, the tools happily uninstalled previous versions and enabled me to open, recompile and deploy my 3.0 beta stuff...

Here are some beta samples updated for RTW

Thursday, 18 June 2009

iPhone OS 3.0 - Safari Geolocation

Having installed iPhone OS 3.0 today, the first thing I wanted to play with (after MMS and Copy/Paste) was the Safari Geographical Location support.

The best example code I found was this iPhone 3.0 geolocation javascript API example... however for some reason the Google 'static map' images wouldn't work for me. I'm not 100% sure why (since the blog post appears to show it working) - but Safari on the iPhone does handle http://maps.google.com URLs in a special way (at least it does if they're anchor/links, in which case it triggers the Maps application).

Anyway, since I was keen to get "something" working, I Googled a basic 'image passthrough proxy' - which seemed to fix the problem.
iPhone safari geolocation

The HTML and javascript is very simple (it's repeated from here).

function handler(location) {
var message = document.getElementById("message");
var loc = location.coords.latitude + "," + location.coords.longitude;
message.innerHTML = "<img src='MapImageHandler.aspx?centerPoint="+ loc +"' />";
message.innerHTML+="<p>Longitude: " + location.coords.longitude + "<br />";
message.innerHTML+="Latitude: " + location.coords.latitude + "<br />";
message.innerHTML += "Accuracy: " + location.coords.accuracy + "</p>";
}
navigator.geolocation.getCurrentPosition(handler);
The MapImageHandler.aspx code is also very short (and was sourced from here).

That's about the most basic geolocation sample you could... now to find something useful to do with it! Thanks to the two authors of the code I stitched together (blog.bemoko.com and guy off CodeProject).

Wednesday, 17 June 2009

Customizing Bing (on your site)

It's fairly easy to create a site-specific, bing-powered search box, using the basic wizard at www.bing.com/siteowner.

However, it turned out to be less obvious how to 'customize' it's behaviour... specifically I wanted the search to search 'sites in Australia' by default. The final result is shown below, and you can try it here



Working with Advanced Queries in the Windows Live Search Box provides some hints about how you can customize the javascript var WLSearchBoxConfiguration={...} which controls how the search box works.

By default it looks like this
var WLSearchBoxConfiguration=
{
"global":{
"serverDNS":"www.bing.com",
"market":"en-AU"
},
"appearance":{
"autoHideTopControl":false,
"width":600,
"height":400,
"theme":"Blue"
},
"scopes":[
{
"type":"web",
"caption":"&#x57;&#x65;&#x62;",
"searchParam":""
}
]
}
which provides a simple web search. To force the search to be "only for sites from Australia" we needed to add a new scope with a searchParam set:
"searchParam":"loc:AU"

Restricting to a specific site/domain is more obvious:
"searchParam": "site:conceptdev.blogspot.com"


It ends up looking like this:
var WLSearchBoxConfiguration=
{
"global":{
"serverDNS":"www.bing.com",
"market":"en-AU"
},
"appearance":{
"autoHideTopControl":false,
"width":600,
"height":400,
"theme":"Blue"
},
"scopes": [
{
"type": "web",
"caption": "this site",
"searchParam": "site:conceptdevelopment.net"
}
,
{
"type": "web",
"caption": "ConceptDev Blog",
"searchParam": "site:conceptdev.blogspot.com"
}
,
{
"type":"web",
"caption":"&#x57;&#x65;&#x62;&#x20;&#x28;&#x41;&#x75;&#x73;&#x74;&#x72;&#x61;&#x6C;&#x69;&#x61;&#x29;",
"searchParam":"loc:AU"
}
,
{
"type":"web",
"caption":"&#x57;&#x65;&#x62;&#x20;&#x28;&#x61;&#x6c;&#x6C;&#x29;",
"searchParam":""
}
]
}
It doesn't look like you need to worry too much about the ASCII-Hex encoding for simple characters (although if you want to encode them, there are plenty of tools).

Tuesday, 9 June 2009

How I read a resumé...

I came across this graphic today - linked from a great post on How to apply for a professional job - and had to post a link to it. Many of the points are funny/humorous - generally because they're (kinda) true! All the ones about attention-to-detail in your CV are 100% spot-on.

Wednesday, 27 May 2009

Twitter spam=FAIL (UPDATE Customer Service=WIN)

Update Nov-09: It's been a few months since I 'let off steam' with the post below. It sounds a bit over-the-top reading it now. Anyway, as you can see in the comments I was recently contact by the company directly and I couldn't be more impressed with how they handled my 'complaint'. That sort of honesty in customer service deserves another look. The remainder of the post reads 'as it was'.

In the normal course of tweeting today, I happened to post
Argh - moving an ASP.NET app that requires Crystal Reports for VS 2003... oh the humanity
Nothing special about that - I often complain about stuff on Twitter... but mostly programming and stuff, not specific products or companies (see When Word of Mouth Got a Permalink) so I was unprepared for what happened next...



W.T.F.!? Okay so Twitter is totally open and there are all sorts of search-bots BUT give-me-a-break with the crappy marketing line and unattended twitter account.



Phew now I feel better :-)

Thursday, 14 May 2009

Microsoft Translator Widget

The Microsoft Translator Widget has been popping up on various sites recently - and now some of mine...

ConceptDevelopment.net in Spanish


Geoquery2008.com in Japanese


It's difficult to tell how useful this will be - unless Google can 'discover' this content is available in other languages it will be difficult to attract foreign-language traffic to Translator-enabled sites. It's all client-side/script-driven, so Google isn't going to get any translated content under normal spidering conditions. Those who land on the content organically may find it helpful I suppose...
I wonder if Live Search does anything special for Translator sites?

Tuesday, 12 May 2009

Draw on Silverlight Virtual Earth Map Control

There are a couple of different projects where I'd like to enable 'drawing' on a map (including RaceReplay.net) - this is a basic first-cut of drawing within the Microsoft VE Map Control.

Each click on the map will start/continue a line. The MouseLeave event is wired to start a 'new' line. Navigating the map (dragging/double-click zoom) also causes points to be drawn - obviously this needs some work...


The two files required to build it are Page.xaml and Page.xaml.cs, the key pieces of code being
private void VEMap_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Map m = (Map)sender;
Location l = m.ViewportPointToLocation(e.GetPosition(m));
if (polyline == null)
CreateNewPolyline(l);
else
polyline.Locations.Add(l);
}
and
private void CreateNewPolyline(Location startPoint)
{
polyline = new MapPolyline();
polyline.Stroke = new SolidColorBrush(Colors.Red);
polyline.StrokeThickness = 2;
var lc = new LocationCollection();
lc.Add(startPoint);
polyline.Locations = lc;
VEMap.Children.Add(polyline);
}
Simple, eh?

p.s. these are plain old straight lines - at the 'continent' level you might expect them to curve as though on a great-circle; I'm not too worried about implementing that right now since the target usage of my drawing is at a much "smaller scale"... however Geoquery2008 does draw great circle lines correctly...

Saturday, 9 May 2009

Silverlight DataContractJsonSerializer Error

Admittedly there is very little excuse for hand-crafting Json output these days, with libraries like Json.NET available, and WCF supporting Json natively. However, I was tweaking an existing ASPX page (that was actually rendering Xaml for a Silverlight 1.0 application) to turn it into a 'service' for Silverlight 2.0... and it seemed like the fastest way to do that was simply replace a whole pile of <s and >s with {}

I got some hints/reminders on how to Consume a JSON object in Silverlight, and found Jsonlint really helpful in tuning the output until it was valid Json.


Then I created a 'matching' object model in Silverlight C#


and wired up the OpenReadCompleted event using DataContractJsonSerializer


Everything LOOKED like it should work, so at first I was confused by this error message:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Object]' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'

After staring blankly at the code for a while, I finally realised where my Json had gone wrong -- at the very root of my Json response (see Jsonlint image above) I was "accidentally" wrapping the entire Json output with an unnecessary [] pair. I guess this meant the Deserializer was expecting to cast into a collection (albeit with a single element), but I was intending the root Json element to be a single object (to match my C# JsonCourse).

The simple fix was removing the enclosing [] so that my Json started off like this instead:
{
"width": 800 ,
"height": 600 ,
"runners": [
{
"name": "mapcanberramarathon",
"points": [
Lesson for tonight is to better understand the underlying Json representation before consuming it (or else use a library rather than hand-craft the output). Anyway now it is fixed RaceReplay.net 2.0 is that much closer to fruition...

Saturday, 2 May 2009

Silverlight "Maps That Bend Upwards"

I was inspired today by HERE & THERE's horizonless projection of Manhattan (via The Map Room: Maps that Bend Upwards).

Using Silverlight 3.0 beta and it's new PlaneProjection feature, I have hooked up three Silverlight Map Controls with different values for RotationX, GlobalOffsetY (vertical displacement) and GlobalOffsetZ (in/out of the page) to create a very crude 'interactive' version of their horizonless-map.

If you have Silverlight 3.0 beta installed, you can try out the Silverlight Virtual Earth Maps That Bend Upwards OR if you don't have the beta installed, you can watch a screencast.


[try it] [watch it]

I've noticed a little bit of weird behaviour on loading (sometimes the 'initial' map of New York doesn't load completely sync'd in all three panels), but after that it seems to work OK - it's just for fun after all.

Sunday, 26 April 2009

ASP.NET Model View Controller (MVC)

Another 'link collection' (along the lines of my MVVM list)... about ASP.NET MVC (Model View Controller)...
Chris Tavares' Building Web Apps without Web FormsChris explains the MVC concepts and in the process builds a simple wiki-like tool - great because it is a more 'real life application' type example than you'll see elsewhere.
Rob Conory on why You Should Learn MVCRob Conery's well-thought-out argument for giving ASP.NET MVC is a great read, with some classic quotes such as:
WebForms is a lie. It’s abstraction wrapped in deception covered in lie sauce presented on a plate full of diversion and sleight of hand. Nothing you do with Webforms has anything to do with the web – you let it do the work for you.
This, friends, is a big deal (at least to me): You’re working in a lie. The web is *not* stateful and works with this stuff called HTML sent across wires using another thing called HTTP – you need to know this, love this, and feel it at the bone level.
He provides seven excellent reasons to back up his assertion (I'm paraphrasing the headings here, you should read the original text):
  1. Testability - yes, automated testing can be conducted much closer to your 'ui surface' without needing actual ui automation (ala WatiN et al)
  2. Control over Html - no 'funky' id munging or VIEWSTATE!
  3. Extensibility (my favourite so far - the Spark View Engine)
  4. Makes you think - and that's a good thing :)
  5. Javascript has 'come of age'
  6. Learn new concepts - what are those ALT.NET guys on about, anyway?
  7. It's fun!
Jeremy D. Miller's Oversimplified ASP.Net MVC Pros and ConsTo sum up:
  • CON: ASP.NET MVC is a 'version 1' product - so be warned
  • PRO: It's easy to customize and extend, to get around point #1
Simple eh?
The Book
Professional ASP.NET MVC 1.0
Written by the "fantastic four" (Rob Conery, Scott Hanselman, Phil Haack, Scott Guthrie), I can only imagine it's a good read since I haven't bought it (yet)...
However, the first chapter by Scottgu(180+ pages) is a free download!, and you can view the sample app - nerddinner.com and download the code.
K. Scott Allen's MSDN article Life And Times of an ASP.NET MVC ControllerIntroduces Routing, Controllers, Action/ActionResult and Helpers.

AND 6 Tips for MVC Model Binding (and validation) - a hidden gem in the MVC framework!
Models incSlightly OT for a pure MVC post - applies to MVVM or any of the related patterns really - but I agree with the premise: Keep your system/tier/layer/whatever boundaries simple (DTOs) and
if there is more application specific needs than a simple DTO can provide, then create an Application Model
I guess that kinda leads into this discussion on creating View Models in MVC - I wondered about the "IEnumerable as the Model Type" in NerdDinner - Stephen discusses a 'proper' ViewModel approach too (see Listing 5 and 6 - although I'm not sure I'd put it in *Controller.cs necessarily).
Los Techies' Jimmy Bogard's How we do MVCThe 'voice of experience' from 9 months of MVC, including advice like:
  • Thin (not FAT) Controllers
  • Strongly-typed views, and discouraging the dictionary part of ViewData
  • Distinct ViewModels (seperate from the domain)
  • No magic strings
  • receive the EditModel as an action parameter, not some collection object
  • and my favourite advice:
    • Use partials when you have common markup, and the data is in your top-level ViewModel object.
    • Use RenderAction when you have common markup, but the information is orthogonal to the main concern of your view. Think like the "login widget" at the top of every screen. A filter is too much indirection for that scenario, RenderAction is very explicit.

Also links to Jeremy D. Miller's "Opinions" on MVC which is full of more sage advice!
ASP.NET MVC - the websiteMicrosoft's 'official' MVC home page - download the bits, watch videos, download templates, download sample applications and link to many more useful blog posts than described above!
VideosFrom Scottgu:
MSDN documentationIf you must...
Prevent Cross-Site Request Forgery (CSRF) using ASP.NET MVC’s AntiForgeryToken() helperThis is a 'specific feature' unlike many of the above links, but an important one IMO...
Your application can be vulnerable to cross-site request forgery (CSRF) attacks not because you the developer did something wrong (as in, failing to encode outputs leads to XSS), but simply because of how the whole Web is designed to work.
ALL developers of internet-accessible websites should be making themselves familiar with XSS/CSRF: how they work and how to protect against them. If this feature makes that easier/simpler using MVC... then that's probably another reason to use MVC!
Check out Stephen Walther's draft ASP.NET MVC Framework Unleashed bookRead the great draft chapters Stephen has generously posted on his blog, provide feedback and then buy the book!



UPDATED: Added How we MVC and MVC Thunderdome Principle. Both provide exactly the kind of real-world 'lessons learned' that I want to read before starting an MVC project - to know that others have experienced real-world problems, found real-world (and neat) solutions, and shared them. Now I'm free to go and make my own new mistakes :)

UPDATED: You should NOT use ASP.NET MVC if... lists some reasons why MVC may not be for you: "You rely on 3rd party vendor controls for lots of the UI" is a good one which may not be 'immediately obvious' to those looking at MVC for the first time.