<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.simple-talk.com/community/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Matt Lee</title><link>http://www.simple-talk.com/community/blogs/thatismatt/default.aspx</link><description>Software Engineer at Red Gate Software, Maker of funky apps.</description><dc:language>en-US</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>Why ASP.NET MVC is better - using 'Hello' as an example</title><link>http://www.simple-talk.com/community/blogs/thatismatt/archive/2009/09/30/75047.aspx</link><pubDate>Wed, 30 Sep 2009 15:12:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:75047</guid><dc:creator>Matt Lee</dc:creator><slash:comments>5</slash:comments><comments>http://www.simple-talk.com/community/blogs/thatismatt/comments/75047.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/thatismatt/commentrss.aspx?PostID=75047</wfw:commentRss><description>&lt;p&gt;In this second post about &lt;a href="http://hello.carsonified.com/"&gt;Hello&lt;/a&gt; (the first can be found &lt;a href="/community/blogs/thatismatt/archive/2009/09/03/ASP_NET_MVC_Twitter_Integration_getting_inside_Hello.aspx"&gt;here&lt;/a&gt;), I'm going to use one of the more complex portions of the app, the event front page, to illustrate some of the various parts of MVC which make writing web apps more intuitive.&lt;/p&gt;

&lt;p&gt;The web app of the Hello project was written in ASP.NET MVC, which is Microsoft's latest addition to the ASP.NET framework. It uses the Model, View, Controller design pattern and is influenced heavily by frameworks like Ruby on Rails.&lt;/p&gt;

&lt;img src="/blogbits/MattLee/HelloEventFrontPage.png"&gt;

&lt;p&gt;&lt;font size="1"&gt;&lt;b&gt;Fig. 1 - The event front page of Hello displays the seating for the event; each chair is represented by a square and if there is a user in the chair we display their twitter avatar.&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;To produce the event page, there are several stages that the app goes through - for an awesome outline of the ASP.NET MVC Request-Handling Pipeline, see &lt;a href="http://www.red-gate.com/products/ants_performance_profiler/be_ahead_of_the_game_poster1.htm"&gt;this poster&lt;/a&gt;. Firstly the URL is routed through to the correct controller. We decided that we wanted the front page for an event to live under a really simple URL: &lt;code&gt;/eventslug&lt;/code&gt;, where &lt;code&gt;eventslug&lt;/code&gt; would be a short string to uniquely identify the event. For example, for the Future of Web Apps event we might have the URL &lt;code&gt;/fowa&lt;/code&gt;. From the event page you can search the users at the event, and we decided the intuitive URL for the search should be &lt;code&gt;/eventslug/search&lt;/code&gt;. You configure the URLs in the Global.asax.cs file as follows:&lt;/p&gt;

&lt;pre&gt;routes.MapRoute(&lt;font color="#0000ff"&gt;null&lt;/font&gt;,&lt;br&gt;  &lt;font color="brown"&gt;"{eventslug}/{action}"&lt;/font&gt;,&lt;br&gt;  &lt;font color="#0000ff"&gt;new&lt;/font&gt; { controller = &lt;font color="brown"&gt;"Event"&lt;/font&gt;,, action = &lt;font color="brown"&gt;"Index"&lt;/font&gt;, }, &lt;font color="green"&gt;// Defaults&lt;/font&gt;&lt;br&gt;  &lt;font color="#0000ff"&gt;new&lt;/font&gt; { eventslug = &lt;font color="#2b91af"&gt;Settings&lt;/font&gt;.EventSlugRegex }       &lt;font color="green"&gt;// Contraints&lt;/font&gt;&lt;br&gt;);&lt;/pre&gt;

&lt;p&gt;From here the framework calls an action on your controller. If you’ve not started using MVC yet, a controller in an object that inherits from the abstract class &lt;code&gt;System.Web.Mvc.Controller&lt;code&gt; and an action is a public method of a controller. The signature for our action that will be called for &lt;code&gt;/fowa&lt;/code&gt; is:&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;font color="blue"&gt;public&lt;/font&gt; &lt;font color="#2b91af"&gt;ActionResult&lt;/font&gt; Index(&lt;font color="blue"&gt;string&lt;/font&gt; eventslug)&lt;/pre&gt;

&lt;p&gt;We call it &lt;code&gt;Index&lt;/code&gt; because that’s the default action that we specified in the routing configuration. The framework will automagically map the value of the &lt;code&gt;eventslug&lt;/code&gt; argument to the value that matches the &lt;code&gt;{eventslug}&lt;/code&gt; portion of the URL; In the case of &lt;code&gt;/fowa&lt;/code&gt; it will be the string &lt;code&gt;"fowa"&lt;/code&gt;*.&lt;/p&gt;

&lt;p&gt;Then, in our action method, we grab the data relevant to the event with the requested event slug, and pass it to the view by calling &lt;code&gt;View()&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;font color="blue"&gt;var&lt;/font&gt; theEvent = _repo&lt;br&gt;    .Events&lt;br&gt;    .SingleOrDefault(e =&amp;gt; e.Slug == eventslug);&lt;br&gt;&lt;font color="blue"&gt;return&lt;/font&gt; View(theEvent);&lt;/pre&gt;

&lt;p&gt;Calling the &lt;code&gt;View&lt;/code&gt; method with &lt;code&gt;theEvent&lt;/code&gt; as an argument means that in the view, the &lt;code&gt;Model&lt;/code&gt; property of the &lt;code&gt;ViewPage&lt;/code&gt; object will be the &lt;code&gt;theEvent&lt;/code&gt; that was just retrieved from the repo. In MVC the view is an aspx page without a code behind class. The view is actually a &lt;code&gt;ViewPage&amp;lt;T&amp;gt;&lt;/code&gt; object, which is a subclass of the old &lt;code&gt;Page&lt;/code&gt; object that you’re familiar with from WebForms, where &lt;code&gt;T&lt;/code&gt; is the type of the &lt;code&gt;Model&lt;/code&gt; property. What this means is that in the view we get intellisense on our domain object:&lt;/p&gt;

&lt;img src="/blogbits/MattLee/HelloViewIntellisense.png"&gt;

&lt;p&gt;&lt;font size="1"&gt;&lt;b&gt;Fig. 2 - Intellisense in the view code on the statically typed &lt;code&gt;Model&lt;/code&gt; property.&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;In the view we also have complete control of our HTML, which was invaluable for this page as we had to get the layout just right in all the major browsers. So we just iterate over our rows of seats rendering the smiley.jpg image for an empty seat (&lt;code&gt;sat == null&lt;/code&gt;) and when someone is in a seat we render their Twitter avatar.&lt;/p&gt;

&lt;pre&gt;&lt;font color="blue"&gt;&amp;lt;&lt;font color="brown"&gt;table&lt;/font&gt; &lt;font color="red"&gt;class&lt;/font&gt;="seatingPlan" &lt;font color="red"&gt;cellpadding&lt;/font&gt;="0" &lt;font color="red"&gt;cellspacing&lt;/font&gt;="0" &lt;font color="red"&gt;border&lt;/font&gt;="0"&amp;gt;&lt;/font&gt;&lt;br&gt;  &amp;lt;% &lt;font color="blue"&gt;var&lt;/font&gt; sats = (&lt;font color="#2b91af"&gt;IList&lt;/font&gt;&amp;lt;&lt;font color="#2b91af"&gt;Sat&lt;/font&gt;&amp;gt;)ViewData[&lt;font color="brown"&gt;"Sats"&lt;/font&gt;]; %&amp;gt;&lt;br&gt;  &amp;lt;% &lt;font color="blue"&gt;foreach&lt;/font&gt; (&lt;font color="blue"&gt;var&lt;/font&gt; row &lt;font color="blue"&gt;in&lt;/font&gt; Model.Seats.GroupBy(s =&amp;gt; s.Row)) { %&amp;gt;&lt;br&gt;    &lt;font color="blue"&gt;&amp;lt;&lt;font color="brown"&gt;tr&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;      &amp;lt;% &lt;font color="blue"&gt;foreach&lt;/font&gt; (&lt;font color="blue"&gt;var&lt;/font&gt; seat &lt;font color="blue"&gt;in&lt;/font&gt; row) { %&amp;gt;&lt;br&gt;        &lt;font color="blue"&gt;&amp;lt;&lt;font color="brown"&gt;td&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;          &amp;lt;% &lt;font color="blue"&gt;var&lt;/font&gt; sat = sats.SingleOrDefault(s =&amp;gt; s.SeatID == seat.SeatID); %&amp;gt;&lt;br&gt;          &amp;lt;% &lt;font color="blue"&gt;if&lt;/font&gt; (sat == &lt;font color="blue"&gt;null&lt;/font&gt;) { %&amp;gt;&lt;br&gt;            &lt;font color="blue"&gt;&amp;lt;&lt;font color="brown"&gt;img&lt;/font&gt; &lt;font color="red"&gt;src&lt;/font&gt;="&lt;/font&gt;&amp;lt;%= Url.Content("~/Content/images/presentation/smiley.jpg") %&amp;gt;&lt;font color="blue"&gt;" /&amp;gt;&lt;/font&gt;&lt;br&gt;          &amp;lt;% } &lt;font color="blue"&gt;else&lt;/font&gt; { %&amp;gt;&lt;br&gt;            &lt;font color="blue"&gt;&amp;lt;&lt;font color="brown"&gt;img&lt;/font&gt; &lt;font color="red"&gt;src&lt;/font&gt;="&lt;/font&gt;&amp;lt;%= sat.User.ImageURL %&amp;gt;&lt;font color="blue"&gt;" /&amp;gt;&lt;/font&gt;&lt;br&gt;          &amp;lt;% } %&amp;gt;&lt;br&gt;        &lt;font color="blue"&gt;&amp;lt;/&lt;font color="brown"&gt;td&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;      &amp;lt;% } %&amp;gt;&lt;br&gt;    &lt;font color="blue"&gt;&amp;lt;/&lt;font color="brown"&gt;tr&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;br&gt;  &amp;lt;% } %&amp;gt;&lt;br&gt;&lt;font color="blue"&gt;&amp;lt;/&lt;font color="brown"&gt;table&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;This is much more intuitive and clear than having to create a user control class which is then dynamically instantiated in the code behind and added as a child control of an ASP &lt;code&gt;TableRow&lt;/code&gt;, which is then in turn added to an ASP &lt;code&gt;Table&lt;/code&gt;, etc. Your code in front would of been basically one line...&lt;/p&gt;

&lt;pre&gt;&lt;font color="blue"&gt;&amp;lt;&lt;font color="brown"&gt;asp&lt;/font&gt;:&lt;font color="brown"&gt;Table&lt;/font&gt; &lt;font color="red"&gt;runat&lt;/font&gt;="server" &lt;font color="red"&gt;ID&lt;/font&gt;="SeatsTable" /&amp;gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;... Totally hiding the complexity in the code behind, which would probably have been a mess of data access code and layout styling knotted together. Which is what you would have done in WebForms.&lt;/p&gt;

&lt;p&gt;So why is this better? There are probably two key differences between WebForms and MVC. Firstly, separation of concerns: MVC encourages you to separate out your domain model from your UI from your URL routing. WebForms actually makes that quite difficult; if anything, the code in front/behind paradigm encourages the reverse. Secondly, no unnecessary leaky abstractions: WebForms tries to hide from the developer the fact that he is working in a world of string manipulation over a stateless protocol. In the simple case this can work well, e.g. the classic click-the-button-to-make-the-label-say-hello example. But in the real world, the abstraction soon gets in the way, and you end up having to work really hard to achieve something quite simple. In MVC there is no abstraction to battle against, you have complete control of all parts of your web app. I’m going to put myself out there and say that MVC should be seen as a replacement to WebForms, as I don’t think there are any real world cases when MVC is not the right choice.&lt;/p&gt;

&lt;p&gt;&lt;font size="1"&gt;* this isn't strictly true, the arguments of an action can be mapped from 1 of three places - the URL, query string paramenters, or form values.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=75047" width="1" height="1"&gt;</description></item><item><title>ASP.NET MVC &amp; Twitter Integration - getting inside 'Hello'</title><link>http://www.simple-talk.com/community/blogs/thatismatt/archive/2009/09/03/ASP_NET_MVC_Twitter_Integration_getting_inside_Hello.aspx</link><pubDate>Thu, 03 Sep 2009 15:39:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:74652</guid><dc:creator>Matt Lee</dc:creator><slash:comments>1512</slash:comments><comments>http://www.simple-talk.com/community/blogs/thatismatt/comments/74652.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/thatismatt/commentrss.aspx?PostID=74652</wfw:commentRss><description>&lt;p&gt;I recently teamed up with &lt;a target="_blank" href="http://twitter.com/ryancarson"&gt;Ryan Carson&lt;/a&gt;, &lt;a target="_blank" href="http://twitter.com/Keirwhitaker"&gt;Keir Whitaker&lt;/a&gt; and &lt;a target="_blank" href="http://twitter.com/mikekus"&gt;Mike Kus&lt;/a&gt; from &lt;a target="_blank" href="http://carsonified.com/"&gt;Carsonified&lt;/a&gt; to write an application called 'Hello', with the catchy tagline &lt;i&gt;"Turn to your neighbour and say..."&lt;/i&gt;, geddit?! The motivation behind the project was to write something within a tight timescale that used a complete Microsoft stack, capped by ASP.NET MVC, and I thought that some of my experiences might be interesting to other people. This post will be the first in a series that will hopefully cover the techy side as well as the 'managerial' / logistical aspects. I'll give an initial overview of the project and its component parts, with some code thrown in to whet your appetite.&lt;/p&gt;

&lt;h2&gt;Overview&lt;/h2&gt;

&lt;blockquote&gt;&lt;i&gt;Hello helps you to meet interesting people at FOWA London. You can say where you're sitting, earn points, badges and post messages to the whole audience.&lt;/i&gt;&lt;/blockquote&gt;

&lt;p&gt;As the description on Hello's &lt;a target="_blank" href="http://hello.carsonified.com/"&gt;front page&lt;/a&gt; says. The basic idea is that it is an app to encourage social interaction at events, namely &lt;a target="_blank" href="http://events.carsonified.com/fowa"&gt;FOWA London&lt;/a&gt;. Unusually, all input in to the app comes from Twitter, so the architecture looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/blogbits/MattLee/HelloArch.png"&gt;&lt;/p&gt;

&lt;p&gt;The arrows show the flow of information - the arrow from the User to Twitter represents the flow of information from the user to Twitter by means of tweeting (unsurprisingly). To give you an example of how this works, if you wanted to join in with this Hello &lt;i&gt;thing&lt;/i&gt; you could &lt;a target="_blank" href="http://twitter.com/thatismatt/status/3294745191"&gt;send a tweet&lt;/a&gt; that looked something like:&lt;/p&gt;

&lt;blockquote&gt;@HelloApp hello !dev #csharp #aspnetmvc #jquery&lt;/blockquote&gt;

&lt;p&gt;This would sign you up for Hello with a category of Developer, and then the hashtags that describe you. Hello gets really interesting on Conference Day when you're able to tweet messages saying where you're sitting, who you've met, tokens you've found or been given, and so on. And why would you want to do all these things? To win points of course - each action has an associated number of points. And why do you want points? Well because the more points you have then, clearly, &lt;i&gt;the cooler you are&lt;/i&gt;. Not only do you look cool though, but you can then also tweet your own personal message and get it seen on the conference home page. A perfect opportunity to let people know you're hiring, or advertise your latest startup. Now that we know the users categories, hashtags and where they're sitting, you can then browse the seating chart and see who is sitting around you, what their interests are, and whether you have anything in common. You can also search the audience for specific names or skillsets (php, designer, CSS3, etc). Simple, but fun.&lt;/p&gt;

&lt;p&gt;But how does all this work?&lt;/p&gt;

&lt;h2&gt;The Bot - Getting tweets from twitter&lt;/h2&gt;

&lt;p&gt;There are a couple of APIs out there for accessing Twitter from .NET code; I went with &lt;a target="_blank" href="http://tweetsharp.com/"&gt;TweetSharp&lt;/a&gt;, which has a &lt;a target="_blank" href="http://martinfowler.com/bliki/FluentInterface.html"&gt;fluent API&lt;/a&gt;; the code for grabbing all the mentions of a particular username looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;font color="blue"&gt;var&lt;/font&gt; tweets = &lt;font color="#2b91af"&gt;FluentTwitter&lt;/font&gt;
    .CreateRequest()
    .AuthenticateAs(
        &lt;font color="#2b91af"&gt;Settings&lt;/font&gt;.TwitterBotUsername,
        &lt;font color="#2b91af"&gt;Settings&lt;/font&gt;.TwitterBotPassword)
    .Statuses()
    .Mentions()
    .Request()
    .AsStatuses();&lt;/pre&gt;

&lt;p&gt;Pretty straight forward.&lt;/p&gt;

&lt;p&gt;Those tweets are then queued and processed, using the repo for storage...&lt;/p&gt;

&lt;h2&gt;The Repo - LINQ to SQL&lt;/h2&gt;

&lt;p&gt;We used LINQ to SQL for the backend, I love it for its simplicity and ease of use. We knew from the outset that we weren't going to have a hugely complex schema, so some of the weaknesses of LINQ to SQL wouldn't be a problem. After creating the database in SSMS, I switched over to Visual Studio and dragged the tables from the Server Explorer on to the Object Relational Designer. This generated all the domain objects for my application. The real highlight for me is that I don't have to mess around with &lt;code&gt;SqlCommand&lt;/code&gt;s or &lt;code&gt;SqlDataReader&lt;/code&gt;s anymore. I love what you get, pretty much, for free, for example:&lt;/p&gt;

&lt;pre&gt;&lt;font color="blue"&gt;var&lt;/font&gt; messages = _repo
    .Messages
    .Where(m =&amp;gt; !m.Offensive
        &amp;amp;&amp;amp; m.User.Points.Sum(p =&amp;gt; p.Amount) &amp;gt; &lt;font color="#2b91af"&gt;Settings&lt;/font&gt;.Thresholds.Silver)
    .OrderBy(m =&amp;gt; (m.User.Created.Millisecond * randomOffset) % 1000)
    .Take(&lt;font color="#2b91af"&gt;Settings&lt;/font&gt;.MaxMessages);&lt;/pre&gt;

&lt;p&gt;Sweet, huh?!&lt;/p&gt;

&lt;h2&gt;The Web App - Intro to ASP.NET MVC&lt;/h2&gt;

&lt;p&gt;For the web portion of the project we used the latest iteration of Microsoft's web framework, ASP.NET MVC. For anyone keen to know more, there are lots of introductions to ASP.NET MVC out there on the &lt;a target="_blank" href="http://www.google.co.uk/search?q=asp.net+mvc+tutorial"&gt;web&lt;/a&gt;. To get up and running we used the &lt;a target="_blank" href="http://www.microsoft.com/web/downloads/platform.aspx"&gt;Web Platform Installer&lt;/a&gt;, which makes the install process real easy. &lt;a target="_blank" href="http://twitter.com/mikekus"&gt;Mike&lt;/a&gt;, the designer working on the project, put together some awesome designs for the main pages of the site; the front page, search, and the conference day page. They looked something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/blogbits/MattLee/HelloConfDay.jpg"&gt;&lt;/p&gt;

&lt;p&gt;I then translated these to view pages, and MVC makes this really simple as you don't have to fight against the HTML produced server controls. Although the responsibility of writing more HTML by hand can be a higher initial overhead, the long term gain of tight control over your markup is well worth it. Specifically, this is what goes in:&lt;/p&gt;

&lt;pre&gt;&amp;lt;% &lt;font color="blue"&gt;foreach&lt;/font&gt; (&lt;font color="blue"&gt;var&lt;/font&gt; message &lt;font color="blue"&gt;in&lt;/font&gt; (&lt;font color="#2b91af"&gt;IQueryable&lt;/font&gt;&amp;lt;&lt;font color="#2b91af"&gt;Message&lt;/font&gt;&amp;gt;)ViewData[&lt;font color="#a31515"&gt;"Messages"&lt;/font&gt;]) { %&amp;gt;
    &lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;div&lt;/font&gt; &lt;font color="red"&gt;class&lt;/font&gt;&lt;font color="blue"&gt;="message"&amp;gt;&lt;/font&gt;
        &lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;blockquote&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;&lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;"&amp;lt;%= message.Text %&amp;gt;"&lt;font color="blue"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;blockquote&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;
        &lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt; &lt;font color="red"&gt;class&lt;/font&gt;&lt;font color="blue"&gt;="author"&amp;gt;&lt;/font&gt;&lt;br&gt;            By @&lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;a&lt;/font&gt; &lt;font color="red"&gt;href&lt;/font&gt;&lt;font color="blue"&gt;="http://twitter.com/&lt;/font&gt;&amp;lt;%= message.Username %&amp;gt;"&amp;gt;&lt;br&gt;            &amp;lt;%= message.Username %&amp;gt;&lt;font color="blue"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;a&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;br&gt;        &amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;
    &lt;font color="blue"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;div&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;&lt;font color="green"&gt;&amp;lt;!-- /.message --&amp;gt;&lt;/font&gt;
&amp;lt;% } %&amp;gt;&lt;/pre&gt;

&lt;p&gt;And the output...&lt;/p&gt;

&lt;pre&gt;&lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;div&lt;/font&gt; &lt;font color="red"&gt;class&lt;/font&gt;&lt;font color="blue"&gt;="message"&amp;gt;&lt;/font&gt;
    &lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;blockquote&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;&lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;"Ben's message is cool!"&lt;font color="blue"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;blockquote&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;
    &lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt; &lt;font color="red"&gt;class&lt;/font&gt;&lt;font color="blue"&gt;="author"&amp;gt;&lt;/font&gt;&lt;br&gt;        By @&lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;a&lt;/font&gt; &lt;font color="red"&gt;href&lt;/font&gt;&lt;font color="blue"&gt;="http://twitter.com/benadderson"&amp;gt;&lt;/font&gt;&lt;br&gt;        benadderson&lt;font color="blue"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;a&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;br&gt;    &amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;
&lt;font color="blue"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;div&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;&lt;font color="green"&gt;&amp;lt;!-- /.message --&amp;gt;&lt;/font&gt;

&lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;div&lt;/font&gt; &lt;font color="red"&gt;class&lt;/font&gt;&lt;font color="blue"&gt;="message"&amp;gt;&lt;/font&gt;
    &lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;blockquote&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;&lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;"Business is booming and we're hiring. Whoop whoop!"&lt;font color="blue"&gt;&lt;br&gt;    &amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;blockquote&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;
    &lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt; &lt;font color="red"&gt;class&lt;/font&gt;&lt;font color="blue"&gt;="author"&amp;gt;&lt;br&gt;        &lt;/font&gt;By @&lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="brown"&gt;a&lt;/font&gt; &lt;font color="red"&gt;href&lt;/font&gt;&lt;font color="blue"&gt;="http://twitter.com/thatismatt"&amp;gt;&lt;br&gt;        &lt;/font&gt;thatismatt&lt;font color="blue"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;a&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;br&gt;    &amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;p&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;
&lt;font color="blue"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="brown"&gt;div&lt;/font&gt;&lt;font color="blue"&gt;&amp;gt;&lt;/font&gt;&lt;font color="green"&gt;&amp;lt;!-- /.message --&amp;gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Lovely, clean HTML that exactly matches what I was given by Mike. Gone are the days when you have to convince your designer that he can't use a div with that class &lt;i&gt;there&lt;/i&gt; because you're using an ASP GridPanel.&lt;/p&gt;

&lt;p&gt;The added flexibility in the View code does give you more power and, as we all know, &lt;i&gt;"With great power comes great responsibility"&lt;/i&gt;. But seriously, you do have to watch that you don't tie yourself in knots with too much code in your view.&lt;/p&gt;

&lt;h2&gt;Wrap up&lt;/h2&gt;

&lt;p&gt;I found the project really interesting, and working with ASP.NET MVC is such a joy coming from Web Forms, and has pacified my framework envy of such creations as &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt; and &lt;a href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt;. The Twitter integration was also challenging, and taught me a lot about writing applications with dependencies on external services. And the fact that the project was all written on such a tight schedule meant it had &lt;i&gt;such&lt;/i&gt; a different feel to the line-of-business projects I'm normally on. I’ll pull out a bit more detail on a few of these topics in the next few posts, but leave a comment if there’s anything specific you’re interested in.&lt;/p&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=74652" width="1" height="1"&gt;</description></item></channel></rss>
