<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6046505610505291871</id><updated>2012-02-16T22:55:53.394+13:00</updated><category term='css design layout'/><category term='asp.net postbacks trick'/><category term='running'/><category term='live'/><category term='daretodreamdifferent'/><category term='nhaml spark'/><category term='programming'/><category term='azure'/><category term='macbook'/><category term='startup'/><category term='advertising'/><category term='aspnetmvc'/><category term='virtualearth'/><category term='nunit testing'/><category term='micro'/><category term='resharper'/><category term='openx'/><category term='mac &quot;vmware fusion&quot; &quot;sql server&quot;'/><title type='text'>Scott McKenzie</title><subtitle type='html'>A collection of short posts covering technology, my start-up website, fitness and anything else I can throw in.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-6887965907859073408</id><published>2009-12-20T12:36:00.018+13:00</published><updated>2009-12-20T22:31:22.625+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='aspnetmvc'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualearth'/><title type='text'>One Way of Using Virtual Earth with ASP NET MVC</title><content type='html'>&lt;span style=";font-family:verdana;font-size:85%;"  &gt; &lt;span style="font-weight: bold;"&gt;The scenario...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have a simple web application displaying places of interest. A page displaying the place of interest will use Bing maps to display a map. Some users will be able edit the place of interest.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Getting started...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/maps/isdk/ajax/"&gt;Maps Interactive SDK&lt;/a&gt; is a great place to get started with Bing maps. Starting with the "I want to show a specific map" example, the output is:&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="html"&gt;DOCTYPE&lt;/span&gt; &lt;span class="attr"&gt;html&lt;/span&gt; &lt;span class="attr"&gt;PUBLIC&lt;/span&gt; &lt;span class="kwrd"&gt;"-//W3C//DTD XHTML 1.0 Transitional//EN"&lt;/span&gt; &lt;span class="kwrd"&gt;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;meta&lt;/span&gt; &lt;span class="attr"&gt;http-equiv&lt;/span&gt;&lt;span class="kwrd"&gt;="Content-Type"&lt;/span&gt; &lt;span class="attr"&gt;content&lt;/span&gt;&lt;span class="kwrd"&gt;="text/html; charset=utf-8"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;      &amp;lt;script type=&lt;span class="str"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;         &lt;span class="kwrd"&gt;var&lt;/span&gt; map = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;         &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;         &lt;span class="kwrd"&gt;function&lt;/span&gt; GetMap()&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;         {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            map = &lt;span class="kwrd"&gt;new&lt;/span&gt; VEMap(&lt;span class="str"&gt;'myMap'&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;            map.LoadMap(&lt;span class="kwrd"&gt;new&lt;/span&gt; VELatLong(47.6, -122.33), 10 ,&lt;span class="str"&gt;'h'&lt;/span&gt; ,&lt;span class="kwrd"&gt;false&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;         }   &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt; &lt;span class="attr"&gt;onload&lt;/span&gt;&lt;span class="kwrd"&gt;="GetMap();"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;='myMap'&lt;/span&gt; &lt;span class="attr"&gt;style&lt;/span&gt;&lt;span class="kwrd"&gt;="position:relative; width:400px; height:400px;"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;   &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This is my starting point.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Adding jQuery and JSON to the mix&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm going to modify the JavaScript GetMap method to initialise the map using jQuery and to represent the map using JSON.&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;$(function() {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;var mapping = {"Lat":-41.229314,"Long":174.879084,"Zoom":18};&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;var map = new VEMap('myMap');&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;var latLong = new VELatLong(mapping.Lat, mapping.Long);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;map.LoadMap(latLong, mapping.Zoom, 'h', false);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;});&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;Now I'm in a position to inject JSON into the page for different maps.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The domain and the database...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that I can express my map as a JSON object I can look at storing this in the database. There are some design factors I want to consider:&lt;br /&gt;&lt;/span&gt;&lt;ol  style="font-family:verdana;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Right now I want to display a basic map, but as the app evolves I'll probably want to do more.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt; I don't know the full feature-set of Bing maps and I don't know what it will be capable off in the future.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;With these in mind I don't want to commit to changing the database schema every time I decide to add something new so I'm happy storing JSON in the database to achieve this.&lt;br /&gt;&lt;br /&gt;Naively, my domain model for places of interest will look like this:&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PlaceOfInterest {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Id {get; set;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Title {get; set;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;  &lt;span style="font-weight: bold;" class="kwrd"&gt;public&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;" class="kwrd"&gt;string&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; Mapping {get; set;}&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Latitude {get; set;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Longitude {get; set;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;I've made the decision to include latitude and longitude values in the object and table as well as the JSON mapping string. This is because I'll probably want to index these values in the database at some point.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mapping the mapping to a map object...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So I have a all the mapping information as JSON, but I like to work with real objects. I'm going to use a lightweight JSON serializer and deserializer to get an object I can work with and get some type-safety in my app.&lt;br /&gt;&lt;br /&gt;My map class is:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[DataContract] &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Map {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;  [DataMember(Name=&lt;span class="str"&gt;"Lat"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Latitude {get; set;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;  [DataMember(Name=&lt;span class="str"&gt;"Long"&lt;/span&gt;)]&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Longitude {get; set;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;  [DataMember]&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Zoom {get; set;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;I've used the DataMember attribute to shorten the output name rather the full name. (This is probably an unnecessary optimisation but it shows something cool we can do when using .NET's System.Runtime.Serialization classes.)&lt;br /&gt;&lt;br /&gt;Now for the heavy(ish)-lifting class for this app:&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Json &lt;span class="kwrd"&gt;where&lt;/span&gt; T: &lt;span class="kwrd"&gt;class&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt;()&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Serialize(T contract)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;  {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    var serializer = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataContractJsonSerializer(&lt;span class="kwrd"&gt;typeof&lt;/span&gt; (T));&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    var stream = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    serializer.WriteObject(stream, contract);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; Encoding.Default.GetString(stream.ToArray());&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;  }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; T Deserialize(&lt;span class="kwrd"&gt;string&lt;/span&gt; json)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;  {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (String.IsNullOrEmpty(json))&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; T();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    var serializer = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataContractJsonSerializer(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(T));&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    var stream = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream(Encoding.Unicode.GetBytes(json));&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; serializer.ReadObject(stream) &lt;span class="kwrd"&gt;as&lt;/span&gt; T;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;  }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;This could be refined somewhat but it does mean I can do the following:&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;PlaceOfInterest thePlace = PlaceRepository.GetARandomPlaceOfInterest();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;Map theMap = &lt;span class="kwrd"&gt;new&lt;/span&gt; Json().Deserialize(thePlace.Mapping); &lt;span class="rem"&gt;// De-serializing&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; json = &lt;span class="kwrd"&gt;new&lt;/span&gt; Json().Serialize(theMap); &lt;span class="rem"&gt;// Serializing&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;Putting it all together for the users I have a page that takes a PlaceOfInterest. (I have to admit that this is my least favourite part of the app because Visual Studio warns about using the MVC magic in script.)&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&amp;lt;PlaceOfInterest&amp;gt;" %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;...&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:Content&lt;/span&gt; &lt;span class="attr"&gt;ContentPlaceHolderID&lt;/span&gt;&lt;span class="kwrd"&gt;="ScriptPlaceHolder"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &amp;lt;script type=&lt;span class="str"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        $(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; mapping = &lt;span style="font-weight: bold;"&gt;&amp;lt;%= Model.Mapping %&amp;gt;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; map = &lt;span class="kwrd"&gt;new&lt;/span&gt; VEMap(&lt;span class="str"&gt;'myMap'&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; latLong = &lt;span class="kwrd"&gt;new&lt;/span&gt; VELatLong(mapping.Lat, mapping.Long);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;            map.LoadMap(latLong, mapping.Zoom, &lt;span class="str"&gt;'h'&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        });&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:Content&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Because the PlaceOfInterest model doesn't natively have a map model I'm going to use a view model for my Edit action to create the Map object.&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Edit&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; Edit() {}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; Edit(PlaceOfInterest placeOfInterest)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;  {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    PlaceOfInterest = placeOfInterest;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span style="font-weight: bold;"&gt;Map = &lt;/span&gt;&lt;span style="font-weight: bold;" class="kwrd"&gt;new&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; Json().Deserialize(placeOfInterest.Mapping);&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;  }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; PlaceOfInterest PlaceOfInterest { get; set; }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;  &lt;span style="font-weight: bold;" class="kwrd"&gt;public&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; Map Map { get; set; }&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;So, the controller is:&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[AcceptVerbs(HttpVerbs.Get)]&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Edit(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;  var model = &lt;span class="kwrd"&gt;new&lt;/span&gt; Edit(Repository.Get(id));&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;  &lt;span class="kwrd"&gt;return&lt;/span&gt; View(model);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;[AcceptVerbs(HttpVerbs.Post)]&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Edit(&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;  &lt;span class="kwrd"&gt;int&lt;/span&gt; id,&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;  [Bind(Prefix = &lt;span class="str"&gt;""&lt;/span&gt;)]PlaceOfInterest placeOfInterest,&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;  [Bind(Prefix = &lt;span class="str"&gt;"Mapping"&lt;/span&gt;)]Domain.Map map)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;  var thePlaceOfInterest = Repository.Get(id);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;  UpdateModel(thePlaceOfInterest);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;  thePlaceOfInterest.Latitude = map.Latitude;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;  thePlaceOfInterest.Longitude = map.Longitude;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;  thePlaceOfInterest.Mapping = &lt;span class="kwrd"&gt;new&lt;/span&gt; Json().Serialize(map); Repository.Save();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;  &lt;span class="kwrd"&gt;return&lt;/span&gt; View(&lt;span class="kwrd"&gt;new&lt;/span&gt; Edit(Repository.Get(id)));&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;map&gt;The edit view page will contain a call to render a partial control.&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt; Html.RenderPartial(&lt;span class="str"&gt;"Map"&lt;/span&gt;, Model.Map); &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/map&gt;&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;The partial control for the Map...&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl&amp;lt;map&amp;gt;" %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;fieldset&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;legend&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Map&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;legend&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;p&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt; &lt;span class="attr"&gt;for&lt;/span&gt;&lt;span class="kwrd"&gt;="Latitude"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Latitude:&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= Html.TextBox(&lt;span class="str"&gt;"Mapping.Latitude"&lt;/span&gt;, Model.Latitude) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= Html.ValidationMessage(&lt;span class="str"&gt;"Mapping.Latitude"&lt;/span&gt;, &lt;span class="str"&gt;"*"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;p&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;p&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt; &lt;span class="attr"&gt;for&lt;/span&gt;&lt;span class="kwrd"&gt;="Longitude"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Longitude:&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= Html.TextBox(&lt;span class="str"&gt;"Mapping.Longitude"&lt;/span&gt;, Model.Longitude)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= Html.ValidationMessage(&lt;span class="str"&gt;"Mapping.Longitude"&lt;/span&gt;, &lt;span class="str"&gt;"*"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;p&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;p&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt; &lt;span class="attr"&gt;for&lt;/span&gt;&lt;span class="kwrd"&gt;="Zoom"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Zoom:&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= Html.TextBox(&lt;span class="str"&gt;"Mapping.Zoom"&lt;/span&gt;, Model.Zoom)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= Html.ValidationMessage(&lt;span class="str"&gt;"Mapping.Zoom"&lt;/span&gt;, &lt;span class="str"&gt;"*"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;p&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;fieldset&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;And that's pretty much it. &lt;span style="font-family:verdana;"&gt;In summary...&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li  style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;I'm using JSON to store all the data necessary to render a Bing map.&lt;/span&gt;&lt;/li&gt;&lt;li  style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;I use a lightweight bit of JavaScript to consume the JSON map representation.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li  style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;For editing the map I deserialize to a domain model and then use a type-safe partial page in ASP.NET MVC.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li  style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;As my needs for mapping increase I don't have the overhead of having to change my database schema. I do have to update the domain model but then my partial view has to be kept up to date.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;This po&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;st doesn't give much of a context to the app itself. For that I recommend &lt;a href="http://www.amazon.com/gp/product/0470384611?ie=UTF8&amp;amp;tag=diabeticbooks&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0470384611"&gt;Scottx2, Rob and Phil book on ASP.NET MVC 1&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-6887965907859073408?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/6887965907859073408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=6887965907859073408&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6887965907859073408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6887965907859073408'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/12/one-way-of-using-virtual-earth-with.html' title='One Way of Using Virtual Earth with ASP NET MVC'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-5978694907091295729</id><published>2009-05-31T18:37:00.007+12:00</published><updated>2009-06-01T12:47:53.220+12:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='startup'/><category scheme='http://www.blogger.com/atom/ns#' term='advertising'/><category scheme='http://www.blogger.com/atom/ns#' term='openx'/><title type='text'>Advertising</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;The advertising revenue model for websites is a common one, even if the intention is to make enough to pay for hosting costs only. An alternative source of funding is direct sponsorship. When you build a site and advertising is your chosen revenue model you may want to implement one or both of these.&lt;br /&gt;&lt;br /&gt;Some points worth mentioning:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;Google's AdSense is a widely used service, but to make money from it you need to have a lot of ad clicks.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;Sponsorship deals may come and go, but revenue from sponsorship can be significant  and particularly appropriate for your site. There is often some great synergy to be found.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;I'm looking at developing some start up sites (on my own and with others) and I have been weighing up  advertising solutions from a business and technical point of view.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;I want to be flexible; sponsorship is possible but in the absence of such deals I want to fall back to Google AdSense or self-advertising or something else; and&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;I want all the typical advertising features and customization; and&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;I don't really want to write one myself.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;Looking around at the Open Source options I didn't see anything that particularly caught my eye in the Microsoft space. It was a quick look admittedly, but usually the best options float to the surface quickly. During my search I came across the OS software &lt;a href="http://www.openx.org/"&gt;OpenX&lt;/a&gt;. And this is where things start to get interesting.&lt;br /&gt;&lt;br /&gt;OpenX is a collection of advertising options.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;It is an Open Source ad server that you can download and begin to play with. You can host it yourself and, from my own experience with ad servers, it is a fully feature one.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;It's not the ASP.NET/SQL Server solution I started looking for. (Check out the details on &lt;a href="http://www.ohloh.net/p/OpenX"&gt;Ohloh&lt;/a&gt;.)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;They offer hosted advertising using the same ad server&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;It comes with a simple interface for configuring customers, websites, campaigns, banners. It literally took miniutes to get a campaign up and running.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;I can use it to deliver Google AdSense and they provide instructions for setting this up.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;Incorporating it onto my site is simply a matter of including some JavaScript. To ensure good performance you can have a single calll returning multiple ads per page.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;You can slice how your ads are delivered; "geographically" is a key one for me. I can also specify custom logic.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;The ad server has an API and is extensible.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;They have a service called the OpenX Market which seems to be a way of increasing your ad revenue in a competitive but safe fashion. I'm yet to delve into this.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;And the cool thing is it's free for up to 100 million ad impressions per month. Ample for the start up sites I'm looking at.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;OpenX is currently attracting a lot of investment interest. Check out this article from &lt;a href="http://www.techcrunch.com/2009/05/26/openx-keeps-on-growing-raises-10-million-more/"&gt;TechCrunch&lt;/a&gt;. It has some strong players and is going forward strongly.&lt;br /&gt;&lt;br /&gt;OpenX and its range of solutions sounds, looks and feels like a winner to me. It meets all the requirements I have in mind (apart from the technology platform - I favour the Microsoft stack) . It easily meets the flexibility I require for the sites that I have in mind.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-5978694907091295729?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/5978694907091295729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=5978694907091295729&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/5978694907091295729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/5978694907091295729'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/05/advertising.html' title='Advertising'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-2302379472594099522</id><published>2009-05-14T11:52:00.007+12:00</published><updated>2009-05-19T19:08:37.945+12:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='asp.net postbacks trick'/><title type='text'>Cross Page Postback to new window</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;I recently had to post to the same page in a new window for a project I was working on. This &lt;a href="http://aspadvice.com/blogs/joteke/archive/2006/11/30/Cross_2D00_page-postbacks-and-form-action.aspx"&gt;post&lt;/a&gt; got me halfway through but I had to vary it to work with my scenario task.&lt;br /&gt;&lt;br /&gt;Setting onclientclick="target='blank'" successfully lets me post to the same page and have it appear in a different tabbed window. But subsequent button clicks on the same page will also send the output to different windows.&lt;br /&gt;&lt;br /&gt;Joteke's post uses JavaScript to remember the original onclientclick information and the uses a timeout to reset the target of the form.&lt;br /&gt;&lt;br /&gt;Rather than use the JavaScript methods he provided I simply use the same trick to reset the form's target back to "target=''".&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;em style="font-family: courier new;"&gt;&lt;/em&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;em style="font-family: courier new;"&gt;&lt;asp:Button ID="AlwaysToNewPageButton" OnClientClick="form1.target='_blank'"&lt;br /&gt;runat="server" Text="Button" PostBackUrl="~/Default2.aspx" /&gt;&lt;/em&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;em style="font-family: courier new;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;asp:Button ID="AlwaysToSelf" OnClientClick="form1.target=''"&lt;br /&gt;runat="server" Text="Button" PostBackUrl="~/Default1.aspx" /&gt;&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;Problem solved. And thanks to Joteke, of course.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-2302379472594099522?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/2302379472594099522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=2302379472594099522&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/2302379472594099522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/2302379472594099522'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/05/cross-page-postback-to-new-window.html' title='Cross Page Postback to new window'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-53008234563967134</id><published>2009-05-02T16:13:00.004+12:00</published><updated>2009-05-02T17:36:50.537+12:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='css design layout'/><title type='text'>CSS Grid Layout</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;A colleague recently told me about some CSS techniques I was completely unaware of. My way of saying thanks is to point you at his &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://mytechworld.officeacuity.com/"&gt;blog&lt;/a&gt;&lt;span style="font-family:verdana;"&gt;.&lt;br /&gt;&lt;br /&gt;One technique, in particular, is the CSS Grid Layout. The grid layout has been around for decades, but it has only recently come into fashion in the web world.&lt;br /&gt;&lt;br /&gt;The CSS Grid Layout is all about breaking your layout into columns using defined styles. Use of a layout will enable faster mocking and prototyping, greater consistency and shorter development. These benefits will increase if you work on multiple projects and use the same grid layout.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;This encouraged me to investigate a few options out there with the follwoing requirements:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;lightweight&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;easy to use&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;flexible&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;cross-browser&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;And certainly nothing complex that will cause me to dream about it at night.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;I came across these two that meet my requirements. I'm sure there are more so feel free to let me know of your experiences and views.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style="font-family: verdana;" href="http://www.blueprintcss.org/"&gt;http://www.blueprintcss.org/&lt;/a&gt;&lt;br /&gt;&lt;a style="font-family: verdana;" href="http://960.gs/"&gt;http://960.gs/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;I've opted for 960's implementation because:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul  style="font-family:verdana;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;the examples on the page looked good&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;there was a short example&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;there is mathematical appeal in the use of "960"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;it delievers what it says it will&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;As I finish this short post I have just found that &lt;a href="http://www.codinghorror.com/blog/archives/000877.html"&gt;Jeff Attwood&lt;/a&gt; as already posted on this. In 2007! I'm only two years late to the party. But looking around and at my own work experience I think a lot of people don't know the party has started!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-53008234563967134?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/53008234563967134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=53008234563967134&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/53008234563967134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/53008234563967134'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/05/css-grid-layout.html' title='CSS Grid Layout'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-5612960921880288417</id><published>2009-04-18T11:12:00.011+12:00</published><updated>2009-04-18T17:02:52.112+12:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac &quot;vmware fusion&quot; &quot;sql server&quot;'/><title type='text'>Mac, VMWare, Visual Studio and Remote SQL Server 2008</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:verdana;"&gt;All my nocturnal development is done on a Mac + VMware Fusion + Vista rig. VMWare runs Vista using NAT. This is basically a note to remind myself how to configure remote SQL Server access over port 1433.&lt;br /&gt;&lt;br /&gt;I need to do this so I can run aspnet_regsql.exe and Visual Studio's server explorer against a remote SQL Server 2008 database.&lt;br /&gt;&lt;br /&gt;In the terminal:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:courier new;"&gt;cd /Library/Application\ Support/VMware\ Fusion/vmnet8&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;sudo chmod o+rw nat.conf&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;sudo vim nat.conf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:verdana;"&gt;Under the [incomingtcp] section add the line ("i" to insert a new line and ":wq" to save and quit):&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1433 = 127.0.0.1:80 // Use the IP address of your VM here.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;" &gt;sudo /Library/Application\ Support/VMware\ Fusion/boot.sh --restart&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Georgia,serif;"&gt;&lt;span style="font-family:verdana;"&gt;And voila! Talking to SQL Server over 1433 works. (This final command does not restart the VM itself.)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-5612960921880288417?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/5612960921880288417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=5612960921880288417&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/5612960921880288417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/5612960921880288417'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/04/mac-vmware-visual-studio-and-remote-sql.html' title='Mac, VMWare, Visual Studio and Remote SQL Server 2008'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-3811025709363736647</id><published>2009-04-05T15:49:00.009+12:00</published><updated>2009-04-08T21:13:07.742+12:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nhaml spark'/><category scheme='http://www.blogger.com/atom/ns#' term='aspnetmvc'/><title type='text'>ASP.NET MVC: Which view engine</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;I'm about to start work on several ASP.NET MVC web applications. I'm debating whether to use the default view engine or another. Before I begin I'll point you at &lt;a href="http://www.hanselman.com/blog/TheWeeklySourceCode30SparkAndNHamlCrazyASPNETMVCViewEngines.aspx"&gt;Scott Hanselman's blog post&lt;/a&gt; on this. He goes into technical detail on two I am considering. I'm not going to reproduce his work, just let you know which view engine I've decided to use and why.&lt;br /&gt;&lt;br /&gt;(I'm also writing this blog from the hip. I just want my thoughts to fall onto the paper and see how it turns out. It's a style I'm trying out...)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Option 1 | Standard ASP.NET MVC Rendering Engine&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This one is closest to the Web Forms rendering engine and closest to the look and feel of HTML. The only thing that bothers me is I feel as though I am forever writing HTML. Then the HTML helper methods come along and it feels like I switch from markup to code.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;It's safe and easy to sell.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;It's no different to writing HTML, really.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;You can't really apply logic to the HTML you want to render.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-weight: bold;"&gt;Option 2 | NHAML&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://andrewpeters.net/2007/12/19/introducing-nhaml-an-aspnet-mvc-view-engine/"&gt;NHAML&lt;/a&gt; has gone for a much more code-like approach to rendering HTML.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;It has scope when it comes to HTML elements meaning you don't have to close them, just like in C#.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;Calls to the MVC HTML helpers are much "closer" meaning I can go from UI to code smartly. As a coder I rather like this.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;From a high level this looks like code more than it looks like HTML.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-weight: bold;"&gt;Option 3 | Spark&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.dejardin.org/home"&gt;Spark&lt;/a&gt; is a new implementation that is still being worked on. Insofar as far as I understand, the HTML is the framework into which you inject logic to control the display of the HTML.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;It looks more like HTML from a distance.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;There are a lot of angle brackets about the place.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;The code integrates with the HTML rather siting outside.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-weight: bold;"&gt;The Choice&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So which one shall I go for? Bear in mind that I haven't actually used NHAML or Spark for a commercial project. NHAML appeals becuase it is more codey. Spark appeals because it quite cleverly integrates code logic and HTML together. Both let you use lgoic to deal with what you want to render.&lt;br /&gt;&lt;br /&gt;I also have to weigh up which I am likely to use in commercial development. The no-brainer is the default rendering engine, but I want to be able to propose alternatives to customers. I think NHAML would be a hard sell to architects and developers alike it looks more complex and different to what they are used to. Spark on the other hand looks easier because it looks more familar even though it seems to have quite a bit of power behind it.&lt;br /&gt;&lt;br /&gt;[A short ponder later...]&lt;br /&gt;&lt;br /&gt;It will be Spark. It it's different. I can do more than the default rendering engine. It looks more like I can sell it into a company. And it feels edge, slightly more exciting than the alternatives.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-3811025709363736647?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/3811025709363736647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=3811025709363736647&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/3811025709363736647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/3811025709363736647'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/04/aspnet-mvc-which-view-engine.html' title='ASP.NET MVC: Which view engine'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-6561403528188863732</id><published>2009-04-02T17:13:00.004+13:00</published><updated>2009-04-05T15:39:51.184+12:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nunit testing'/><title type='text'>NUnit in the Shadows</title><content type='html'>&lt;span style="font-family: verdana;font-size:85%;" &gt;I was working on a suite of tests using NUnit recently. One of the libraries I was testing has files that are copied to a folder relative to itself. The NUnit test verifying access failed but when run as part of the application everything worked as expected.&lt;br /&gt;&lt;br /&gt;The code causing the issue was building the file path using the the assembly's Location property.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Assembly.GetExecutingAssembly().Location&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In normal usage this was working as expected; a file URI was being returned that I could parse using the Uri class and pull out the directory. Under NUnit usage this was giving me a completely different location that did not have the expected files. It turns out that NUnit employs a .NET feature called Shadow Copying.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Shadow copying allows assemblies that are used in an application domain to be updated without unloading the application domain. This is particularly useful for applications that must be available continuously, such as ASP.NET sites."&lt;/span&gt; - &lt;/span&gt;&lt;span style="font-family: verdana;font-size:85%;" &gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms404279.aspx"&gt;MSDN&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;font-size:85%;" &gt;&lt;br /&gt;NUnit uses this mechanism to allow assemblies to be reloaded easily as part of the edit and debug process. You can get an indication of whether the assembly has been shadow copied using the following boolean property (see &lt;a href="http://msdn.microsoft.com/en-us/library/system.appdomain.shadowcopyfiles.aspx"&gt;MSDN&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;AppDomain.CurrentDomain.ShadowCopyFiles&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If true you can use the CodeBase property in place of Location.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Assembly.GetExecutingAssembly().Codebase&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An alternative option is to disable shadow copying in NUnit although the NUnit site seems to discourage this so I suspect there are some downstream effects (see &lt;a href="http://www.nunit.org/index.php?p=optionsDialog&amp;amp;r=2.4"&gt;NUnit&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-6561403528188863732?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/6561403528188863732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=6561403528188863732&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6561403528188863732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6561403528188863732'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/04/nunit-in-shadows.html' title='NUnit in the Shadows'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-6209603587445701341</id><published>2009-01-16T14:05:00.005+13:00</published><updated>2009-01-16T14:12:02.054+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='macbook'/><title type='text'>My McBook</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: verdana;"&gt;When I ordered my last laptop, an Alienware, it took months to arrive. I did, during that period, travel to Japan and Tahiti. By the time I received it I was majorly underwhelmed.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;I ordered a custom Apple Macbook lat weekend. Within a week it was with me. Check out the tracking...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style="font-family: verdana;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_BFn2xhfJGhI/SW_esGQ8MwI/AAAAAAAAAIo/vCdE17Tp28o/s1600-h/tnt.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 314px; height: 320px;" src="http://2.bp.blogspot.com/_BFn2xhfJGhI/SW_esGQ8MwI/AAAAAAAAAIo/vCdE17Tp28o/s320/tnt.jpg" alt="" id="BLOGGER_PHOTO_ID_5291692936360899330" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Suffice to say, I am super excited.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-6209603587445701341?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/6209603587445701341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=6209603587445701341&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6209603587445701341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6209603587445701341'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/01/my-mcbook.html' title='My McBook'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_BFn2xhfJGhI/SW_esGQ8MwI/AAAAAAAAAIo/vCdE17Tp28o/s72-c/tnt.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-6290341856779134136</id><published>2009-01-09T11:02:00.008+13:00</published><updated>2009-01-10T12:36:35.413+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='azure'/><category scheme='http://www.blogger.com/atom/ns#' term='micro'/><category scheme='http://www.blogger.com/atom/ns#' term='daretodreamdifferent'/><category scheme='http://www.blogger.com/atom/ns#' term='live'/><title type='text'>Dare to Dream Different Challenge</title><content type='html'>&lt;span style=";font-family:verdana;font-size:85%;"  &gt;Last year I entered a Microsoft competition to promote the .NET Micro Framework. The entrance site is still there at http://dreamdifferentcontest.com.  Well, I entered in the professional category and just found out today that I made it to the semi-finals.&lt;br /&gt;&lt;br /&gt;Strictly speaking, I am just a "potential" semi-finalist and I need to sign a few forms and submit some photos first. Then they send me the development kit. Hopefully my new laptop will have arrived by then.&lt;br /&gt;&lt;br /&gt;The idea is to create a prototype for a low-cost home security network that anyone can install and at the same time take advantage of commodity wireless routers.&lt;br /&gt;&lt;br /&gt;The solution itself will include the .NET Micro Framework, Azure services and Live Services. The solution I have in mind should see these integrate quite nicely and at the same time provide for quite a lean solution.&lt;br /&gt;&lt;br /&gt;Wish me luck!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-6290341856779134136?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='' href='http://dreamdifferentcontest.com/round1_winners.aspx' length='0'/><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/6290341856779134136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=6290341856779134136&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6290341856779134136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6290341856779134136'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2009/01/dare-to-dream-different-challenge.html' title='Dare to Dream Different Challenge'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-5161731090063527002</id><published>2008-08-20T20:39:00.002+12:00</published><updated>2008-08-20T21:02:51.402+12:00</updated><title type='text'>Ohloh</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: verdana;"&gt;Having recently bought a house in the sticks I have the opportunity to listen to podcasts once again on my commute. A favourite is Scott Hanselman. One of the topics he regularly discusses is the reading (and understanding) of code to improve one's own ability and skill in this craft.&lt;br /&gt;&lt;br /&gt;This is something I intend to pursue. But what should I go for? Well, I was recently introduced to Ohloh. It is a site that trawls across Open Source projects and gathers various metrics about the projects and reports on them.&lt;br /&gt;&lt;br /&gt;I get a lot of geek-pleasure programming C#so my first prt of call was to the C# projects that are there. I was quite pleased to see a few hundred C# projects out there with a very encouraging upward trend.&lt;br /&gt;&lt;br /&gt;C# doesn't seem to be "up there" at the moment, but there are some big and very well-known projects in the way (FireFox, Ubuntu, Subversion, etc).&lt;br /&gt;&lt;br /&gt;Projects that I think will be interesting to look through include Spring.NET, CruiseControl.NET, Mono (the highest ranked C# project).&lt;br /&gt;&lt;br /&gt;As I was trawling through it did occur to me that writing a Linq to Subversion library would be fun and a great way to get into LINQ in a serious fashion. I've made a note to investigate this and pursue further. :D&lt;br /&gt;&lt;br /&gt;So, I have a few things to look into. Now to make sure time to pursue them.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-5161731090063527002?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/5161731090063527002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=5161731090063527002&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/5161731090063527002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/5161731090063527002'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2008/08/ohloh.html' title='Ohloh'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-4169154222229904935</id><published>2008-03-15T23:25:00.004+13:00</published><updated>2008-03-15T23:41:19.355+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>The Pragmatic Programmer</title><content type='html'>&lt;span style="font-family:Verdana;font-size:85%;"&gt;After almost 10 years of commercial software development I am sorry to say that I started reading "The Pragmatic Programmer" by Hunt and Thomas. Sorry. Because I should have read it 9-10 years ago.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;The piece of pragmatic advice they offer that resounded the most with me was kind of hidden away compared to lots of other great advice on offer. It's in the section 'Stone Soup and Boild Frogs'. It goes, "Be a Catalyst for Change". They also provide a quote  attributed to Rear Admiral Dr. Grace Hopper:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;"It's easier to ask forgiveness than it is to get permission."&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;I'm sure, that as a Rear Admiral, he would not do something that was contrary to the greater good, contrary to the cause he was fighting, beyond appropriate timeframes and without risks suitably mitigated. With these holding true, then what a great way to proceed.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-4169154222229904935?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/4169154222229904935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=4169154222229904935&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/4169154222229904935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/4169154222229904935'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2008/03/pragmatic-programmer.html' title='The Pragmatic Programmer'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-5433371251715609883</id><published>2008-03-10T21:12:00.009+13:00</published><updated>2008-03-12T20:29:09.791+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='aspnetmvc'/><title type='text'>MVC Routing - Part 1</title><content type='html'>&lt;span style="font-family:verdana;font-size:85%;"&gt;ASP.NET MVC CTP2 was released recently with a few functional changes to URL routing. Hopefully this will give you an overview of what you can do with the out of the box implementation.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;First of all, I read somewhere that the routing infrastructure of MVC has been designed such that it can be used in non-MVC implementations. I can't find where I read that, so I can't speculate if that means ASP.NET implementations or further afield... I'll update this log when I find out. Oh, the possibilities...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;Gotchas!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;1. Order is important. When the entered URL is processed the first matching URL will be used. Some IIS routing products let you specify conditions under which you can continue.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;2. The URL parameter specifier no longer uses square brackets but curly ones.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;Named Routes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;The obvious example will be (from &lt;a href="http://quickstarts.asp.net/3-5-extensions/mvc/mvcurlrouting.aspx"&gt;http://quickstarts.asp.net/3-5-extensions/mvc/mvcurlrouting.aspx&lt;/a&gt;):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;RouteTable.Routes.Add(new Route&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;Url = "Default.aspx",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;Defaults = new { controller = "Home", action = "Index" },&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;RouteHandler = new MvcRouteHandler()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;When the &lt;a href="http://localhost/default.aspx"&gt;http://localhost/default.aspx&lt;/a&gt; URL is processed it will redirect to the Home controller's Index method.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;Such URLs can be arbitrarily complex.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;strong&gt;Dynamic Routes&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;Dynamic routes are more interesting and open up a lot of opportunities, especially in the SEO space.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;RouteTable.Routes.Add(new Route&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;Url = "auctions/show/{id}/{title}",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;Defaults = new&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;{&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;controller = "Auctions",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;action = "Show,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;title = (string)null},&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;RouteHandler = new MvcRouteHandler()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#009900;"&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;This is a little more complex, so I'll point out a couple of items:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;1. The URL pattern contains two parametised segments; id and title. This means that the pattern matching will look for something beginning with "auctions/show/" and one further element "id".&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;2. I have not provided a default value for "id", but I have for "title". This is because for this URL to work I really require an ID for the auction, but the title is optional but incredibly useful for SEO.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;3. The controller I want to use is AuctionsController and the method on it is Show(int id, string title).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;Pretty simple. I'll drill down into some more examples and other features of the Route class, specifically Contraints and Data Tokens in subsequent posts.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:85%;"&gt;I'm going to spend some time on the ASP.NET message board and use that to drive some further posts. Or if anyone has a question...&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-5433371251715609883?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/5433371251715609883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=5433371251715609883&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/5433371251715609883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/5433371251715609883'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2008/03/mvc-routing-part-1.html' title='MVC Routing - Part 1'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-373184392953133901</id><published>2008-03-10T17:29:00.005+13:00</published><updated>2008-03-12T21:12:07.145+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='running'/><title type='text'>March 10th, 2008 - Training</title><content type='html'>A friend recommended a great site for running training: &lt;a href="http://www.halhigdon.com/"&gt;http://www.halhigdon.com/&lt;/a&gt;. I'm going to take his intermediate training program and pursue that for a while. The plan for this week is:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;M - 5k&lt;br /&gt;T - 6 x 400m (interval, 200m easy)&lt;br /&gt;W - 5k&lt;br /&gt;T - rest&lt;br /&gt;F - 6.5k&lt;br /&gt;S - 10k&lt;br /&gt;S - rest&lt;br /&gt;&lt;br /&gt;&lt;p&gt;And the results...&lt;br /&gt;&lt;/p&gt;Monday. Max HR was about 180 bpm; slightly faster than it had to be. Completed in 28 minutes. A goos start.&lt;br /&gt;Tuesday. Killer workout, for all the wrong reasons. Incline of 4 degrees and a running speed of 4 kph. I never knew 400m could take so long. Looking forward to gentle 5k tomorrow.&lt;br /&gt;Wednesday. Easy 5k. 11k max. Max HR 170 BPM. Fast recovery.&lt;br /&gt;Thursday. Yaaay! for rest days.&lt;br /&gt;Friday. TBC&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-373184392953133901?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/373184392953133901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=373184392953133901&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/373184392953133901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/373184392953133901'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2008/03/march-10th-2008-training.html' title='March 10th, 2008 - Training'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-7462492042155547711</id><published>2008-03-08T15:28:00.004+13:00</published><updated>2008-03-10T21:11:24.635+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='startup'/><title type='text'>Startup - Genesis</title><content type='html'>I've always had ideas for things; businesses, books, ventures, adventures. I have decided to take one of these ideas as I can use it as an umbrella for a number of others. The premise is simple but it &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;definitely&lt;/span&gt; has some Web 2.0/collaborative angles.&lt;br /&gt;&lt;br /&gt;If it works... Great! If people get some fun out of it... Great! If I learn from it... Great!&lt;br /&gt;&lt;br /&gt;I'm going to keep the basic idea under wraps for now, but I'm going to share some of the progress I make and the decisions I choose.&lt;br /&gt;&lt;br /&gt;I'll keep you posted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-7462492042155547711?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/7462492042155547711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=7462492042155547711&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/7462492042155547711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/7462492042155547711'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2008/03/startup-genesis.html' title='Startup - Genesis'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-2697630183168927848</id><published>2008-03-06T14:24:00.005+13:00</published><updated>2008-03-06T23:04:46.444+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='running'/><title type='text'>Training</title><content type='html'>Decided to go for an easy run today in the gym.&lt;br /&gt;&lt;br /&gt;Having done some interval training a couple of days ago I thought I'd do something similar and opted for a hill session. The treadmills hill programme gave me an option of 1-20. I wasn't, and still am not, sure of what these unit represent so I went low. Five.&lt;br /&gt;&lt;br /&gt;Five it turns out feels like doing an unsupported run up the Eiger. 13 km/h was a little too much for me and I had to take some time out to bring my heart rate down from the 180s.&lt;br /&gt;&lt;br /&gt;Still, at the end it felt like a great run.&lt;br /&gt;&lt;br /&gt;I think there are a couple of 5k runs ciming up in April so I am aiming to do one or both of those. Apparently there is a cold beer at the end. Mmmm...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-2697630183168927848?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/2697630183168927848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=2697630183168927848&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/2697630183168927848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/2697630183168927848'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2008/03/training.html' title='Training'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-1555684373992223709</id><published>2008-03-05T20:40:00.005+13:00</published><updated>2008-03-05T22:40:53.033+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='resharper'/><title type='text'>Wellington .NET User Group Talk</title><content type='html'>Today, I did a short talk at the Wellington .NET User Group. It was a full house at Xero's HQ and hosted by Kirk Jackson.&lt;br /&gt;&lt;br /&gt;There were some experienced speakers there including Jeremy Boyd and Kirk Jackson, but hats off to Nathan (Nan) Li. He did a great presentation on Linq to SQL and in a very short space of time covered a lot of detail I hadn't known (or understood!) about Linq to SQL. I shall convince him to post his presentation shortly and add a link here. :)&lt;br /&gt;&lt;br /&gt;I entitled the presentation:&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;span style="color:#336666;"&gt;&lt;strong&gt;ReSharper&lt;/strong&gt;&lt;br /&gt;the most intelligent add-in to visual studio...&lt;br /&gt;... but only if you use it!&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I thought that rather than cover its usual features (refactoring, templating, formatting and code generating) I would focus on just one not-so obvious feature (not obvious because it is so intuitive to use).&lt;br /&gt;&lt;br /&gt;ReSharper offers static code analysis that is superior to Visual Studio's (and don't get me wrong, I love Visual Studio). It indicates in the scroll bar where the errors are, the severity of the error and suggests possible resolutions.&lt;br /&gt;&lt;br /&gt;This analysis and subsequent validation is great. And that is was the point of my talk:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;&lt;em&gt;ReSharper can form a key step in your development process just by being there. Without any additional investment and no additional learning and no real effort.&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Fix Sooner Rather Than Later&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;ReSharper lets you know before you even start compiling, debugging and stepping&lt;br /&gt;through code that you have erred. This enables you to fix errors, add unit&lt;br /&gt;tests, adjust your approach if necessary, all before having to hit that "F5"&lt;br /&gt;key.&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;This plays into my favourite approach of "the earlier fix it, the less costly it is". If you have code that makes it to test and fails that is more costly than code that doesn't fail. The same can be true within the development process prior to test.&lt;/p&gt;&lt;/blockquote&gt;&lt;span style="font-size:0;"&gt;&lt;strong&gt;&lt;span style="font-size:100%;"&gt;Code Reviews&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;If you present your code to be reviewed and ReSharper is running showing even&lt;br /&gt;just a single negative indicators in the scroll bar then you &lt;em&gt;will&lt;/em&gt; have&lt;br /&gt;some explaining to do to your peers.&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;If you resolve the issues that require it then the remaining debate will have so much more value. As you progress through the lifecycle then ultimately your code review will be able to focus more and more on the true intent of the code and not the noise from general coding errors.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;Pair Programming&lt;/strong&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If you put two developers together and a little red warning pops up, neither&lt;br /&gt;will let that go. But more than that it means these two valuable resources can&lt;br /&gt;focus on the code and not the more mundane coding issues.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-1555684373992223709?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/1555684373992223709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=1555684373992223709&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/1555684373992223709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/1555684373992223709'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2008/03/wellington-net-user-group-talk.html' title='Wellington .NET User Group Talk'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6046505610505291871.post-6975008056816115199</id><published>2008-03-05T16:30:00.001+13:00</published><updated>2008-03-05T20:35:49.620+13:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='running'/><title type='text'>Wellington Round the Bays, 2008</title><content type='html'>It's in the past now, but I ran the Wellington Round the Bays race; 7km, flat with a lovely sunny day and road and great weather. Perhaps too hot, but 4km into it the local fire service were providing a shower of cold wet water.&lt;br /&gt;&lt;br /&gt;Although I tried hard not to I did end up speeding up toward the end. That was bad. The desire to be sick was pretty big. And with all those people there to see. I had to walk a little. Grrrr. There will be no walking next time!&lt;br /&gt;&lt;br /&gt;I completed the race in 31 minutes and 34 seconds. I don't think that was too bad given my level of fitness and time to train.&lt;br /&gt;&lt;br /&gt;My training was pretty desperate. I started a few weeks earlier, but things started getting in the way and I ended up loosing about a week on the run up. I managed to get an easy 5k treadmill session the day before, but the wedding reception that night probably didn't leave me in too fit a state for the next day.&lt;br /&gt;&lt;br /&gt;I'm going to aim to do a better 5k in April. So I'll let you know how that goes...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6046505610505291871-6975008056816115199?l=objektivs.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objektivs.blogspot.com/feeds/6975008056816115199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6046505610505291871&amp;postID=6975008056816115199&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6975008056816115199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6046505610505291871/posts/default/6975008056816115199'/><link rel='alternate' type='text/html' href='http://objektivs.blogspot.com/2008/03/wellington-round-bays-2008.html' title='Wellington Round the Bays, 2008'/><author><name>Scott</name><uri>http://www.blogger.com/profile/09411389820839111715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
