<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/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>Jim O'Neil's Blog : MVC</title><link>http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx</link><description>Tags: MVC</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Come on Baby, Light Your Fire</title><link>http://blogs.msdn.com/jimoneil/archive/2009/09/30/come-on-baby-light-your-fire.aspx</link><pubDate>Thu, 01 Oct 2009 06:21:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9901636</guid><dc:creator>joneil</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/9901636.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=9901636</wfw:commentRss><description>&lt;p&gt;…for ASP.NET MVC and Windows 7, that is.&amp;#160; The &lt;a href="http://msdnevents.com/firestarter/index.html"&gt;Firestarter event series&lt;/a&gt; is dedicated to providing a day-long, free set of technical sessions all focused on getting you up to speed on using a specific technology.&amp;#160; It’s an opportunity to immerse yourself in the topic at hand and get the relevant details from Microsoft speakers, MVPs, and community experts so that you can quickly start applying the technology to your own projects.&lt;/p&gt;  &lt;p&gt;While these are live events, there’s an on-line component as well, so even if you’re not able to be there in person, you can still “attend” via the live webcasts of each event.&amp;#160;&amp;#160; Additionally, past sessions (such as the &lt;a href="http://msdnevents.com/firestarter/#dev_ondemand"&gt;Silverlight Firestarter&lt;/a&gt; held in Seattle on Sept. 17th) are available for viewing on demand.&lt;/p&gt;  &lt;p&gt;There’s two events coming up shortly, one focused on the developer audience and another on the IT Professional audience.&amp;#160; What a great way to open the “Doors” (pun intended) to learning!&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="100%"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" colspan="2" align="center"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/ComeonBabyLightYourFire_11AB8/image_thumb.png" width="240" height="50" /&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" align="center"&gt;         &lt;p&gt;&lt;strong&gt;ASP.NET MVC Firestarter &lt;/strong&gt;&lt;/p&gt;          &lt;p&gt;New York City&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" align="center"&gt;         &lt;p&gt;&lt;strong&gt;Windows 7 Firestarter&lt;/strong&gt;&lt;/p&gt;          &lt;p&gt;Alpharetta, Georgia&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" align="center"&gt;         &lt;p&gt;Saturday, October 3rd            &lt;br /&gt;8:30 a.m. – 5:15 p.m. (ET) &lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" align="center"&gt;         &lt;p&gt;Saturday, October 17th            &lt;br /&gt;8:00 a.m. – 4:45 p.m. (ET) &lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="center"&gt;         &lt;p&gt;&lt;em&gt;&lt;strong&gt;In-person event sold out!&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;          &lt;p&gt;&lt;a href="http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032424194&amp;amp;EventCategory=2&amp;amp;culture=en-US&amp;amp;CountryCode=US"&gt;Register for the Live Meeting&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td align="center"&gt;         &lt;p&gt;&lt;a href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032424192&amp;amp;Culture=en-US"&gt;Register for In-person event&lt;/a&gt; &lt;/p&gt;          &lt;p&gt;&lt;a href="http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032424195&amp;amp;EventCategory=2&amp;amp;culture=en-US&amp;amp;CountryCode=US"&gt;Register for Live Meeting&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9901636" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/New+York/default.aspx">New York</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Windows+7/default.aspx">Windows 7</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Firestarter/default.aspx">Firestarter</category></item><item><title>NerdDinner On Azure – Take 2</title><link>http://blogs.msdn.com/jimoneil/archive/2009/07/27/nerddinner-on-azure-take-2.aspx</link><pubDate>Tue, 28 Jul 2009 04:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9848506</guid><dc:creator>joneil</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/9848506.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=9848506</wfw:commentRss><description>&lt;p&gt;At last week’s &lt;a href="http://blogs.msdn.com/jimoneil/archive/2009/06/02/greater-buffalo-it-dev-day-july-21st.aspx" target="_blank"&gt;Greater Buffalo IT/Dev Day&lt;/a&gt;, I did an overview of the &lt;a href="http://www.microsoft.com/azure/default.mspx" target="_blank"&gt;Windows Azure Platform&lt;/a&gt; (the recently rebranded Azure Services Platform).&amp;#160; Rather than do a tired “Hello World” example, I thought it would be more interesting to talk about a more substantial application, so &lt;a href="http://nerddinner.com/" target="_blank"&gt;NerdDinner&lt;/a&gt; came to mind.&amp;#160; The fact that it’s a great application to talk about &lt;a href="http://www.asp.net/mvc/" target="_blank"&gt;ASP.NET MVC&lt;/a&gt; was just a plus, and although we didn’t focus on MVC, the context of the talk highlighted the fact that an ASP.NET MVC application at some level is “just another .NET web app”.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://cid-cd719ef6510408a8.skydrive.live.com/browse.aspx/Buffalo%20IT-Dev%20Day/Azure" target="_blank"&gt;sample code I used&lt;/a&gt; is available on my SkyDrive, but I wanted to give a little bit of insight into how it was developed, as well as give credit where credit is due.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/mpapas" target="_blank"&gt;Michael Papasevastos&lt;/a&gt;, a colleague at Microsoft, did most of the work!&amp;#160; Back in June &lt;a href="http://blogs.msdn.com/mpapas/archive/2009/06/25/nerddinner-on-azure.aspx" target="_blank"&gt;he blogged&lt;/a&gt; about the steps he took to port NerdDinner to Azure, and he made the &lt;a href="http://blogs.msdn.com/mpapas/attachment/9804106.ashx" target="_blank"&gt;source code available&lt;/a&gt; as well.&lt;/p&gt;  &lt;p&gt;To that starting point, I made a few modifications.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Rebranding&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://nerdbytes.cloudapp.net"&gt;&lt;img style="border-right-width: 0px; margin: 0px 15px 5px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="NerdBytes" border="0" alt="NerdBytes" align="left" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/NerdDinnerOnAzureTake2_E155/logo_3.png" width="126" height="45" /&gt;&lt;/a&gt;I rebranded the application to NerdBytes, in part to eliminate confusion among the various tweaks that folks have made to NerdDinner, and also since &lt;a href="http://nerddinner.cloudapp.net/" target="_blank"&gt;nerddinner.cloudapp.net&lt;/a&gt; was already claimed by Michael’s app!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Azure Table Storage changes&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I noticed an issue in Michael’s choice of PartitionKey and RowKey for &lt;a href="http://msdn.microsoft.com/en-us/library/dd179338.aspx" target="_blank"&gt;Azure Table Storage&lt;/a&gt;.&amp;#160; The scheme he proposes doesn’t handle multiple dinners at the same date and time (the RSVPs used only the date and time of the event as the foreign key).&amp;#160; That was easily handled via the introduction of GUIDs and minor changes to the existing code.&amp;#160; So, in my implementation I use:&lt;/p&gt;    &lt;table border="1" cellspacing="0" cellpadding="3"&gt;&lt;tbody&gt;       &lt;tr bgcolor="#777777"&gt;         &lt;td valign="top" width="83"&gt;Entity&lt;/td&gt;          &lt;td valign="top" width="136"&gt;PartitionKey&lt;/td&gt;          &lt;td valign="top" width="180"&gt;RowKey&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="83"&gt;Dinner&lt;/td&gt;          &lt;td valign="top" width="136"&gt;GUID&lt;/td&gt;          &lt;td valign="top" width="180"&gt;“Host:” + host’s user ID&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="83"&gt;RSVP&lt;/td&gt;          &lt;td valign="top" width="136"&gt;GUID (from Dinner)&lt;/td&gt;          &lt;td valign="top" width="180"&gt;attendee user ID&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;    &lt;p&gt;Wondering why I preface the RowKey of Dinner with the text &amp;quot;&lt;strong&gt;Host:&lt;/strong&gt;&amp;quot;? When you host a dinner, the business logic is to automatically include a RSVP for yourself.&amp;#160; So, presume that Dinner’s RowKey were just the host’s user id.&amp;#160; If that were the case, we’d&amp;#160; now have a record in Dinner and a record in RSVP with exactly the same PartitionKey and RowKey combination.&amp;#160; &lt;/p&gt;    &lt;p&gt;In development storage, it doesn’t immediately appear to be a big deal, because there Azure storage is ‘faked’ by using local relational database tables, and Dinner and RSVP are different tables.&amp;#160; In Azure storage though, there is no concept of schematized data, and every item is essentially a property bag uniquely identified by PartitionKey and RowKey.&amp;#160; Without the “&lt;strong&gt;Host:&lt;/strong&gt;” preface there would be a Dinner entity and an RSVP entity with the same key, and that is verboten, resulting in an exception (both in the Development Fabric and production).&amp;#160; Of course, this means that my design won’t support two dinners hosted by the same person at the same time, but since I haven’t yet figured out how to break the time-space continuum, it’s not an issue for me here.&lt;/p&gt;    &lt;p&gt;In this particular case, I’m not focusing on scalability per se, but &lt;a href="http://www.25hoursaday.com/weblog/2009/01/07/SomeThoughtsOnChoosingPartitionKeysInWindowsAzuresTableStorage.aspx" target="_blank"&gt;here’s an interesting look&lt;/a&gt; at how the choices of PartitionKey and RowKey can affect your application’s ability to scale.&amp;#160; In this case, I’m actually in lock-step with the post’s conclusions, since the GUID is the primary key.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Worker Role Addition&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The original implementation of NerdDinner is a fairly compact Web application, but for my demo, I really wanted to introduce a &lt;a href="http://msdn.microsoft.com/en-us/library/dd179341.aspx#Subheading1"&gt;worker role&lt;/a&gt; and use &lt;a href="http://msdn.microsoft.com/en-us/library/dd179363.aspx"&gt;Azure’s queue storage&lt;/a&gt; to communicate between it and the existing Web role.&amp;#160; To that end, I added a feature that e-mails the host of the dinner whenever a new RSVP has been recorded.&lt;/p&gt;    &lt;p&gt;To implement an e-mail agent in Azure, take a look at fellow ‘softie &lt;a href="http://blogs.msdn.com/davidlem/archive/2009/01/08/windows-azure-sending-smtp-emails.aspx" target="_blank"&gt;David Lempher’s blog article&lt;/a&gt;.&amp;#160; It’s pretty much what I &lt;strike&gt;stole&lt;/strike&gt; researched for my own implementation; I used my live.com account as the SMTP relay, and included the information as part of the &lt;code&gt;serviceConfiguration.cscfg&lt;/code&gt; file.&amp;#160; In code, I rely on the &lt;code&gt;RoleManager.GetConfiguration&lt;/code&gt; setting to access the SMTP account information, and since it’s in the configuration file, I can modify the settings in production via the Windows Azure Platform portal without bringing down my application.&lt;/p&gt;    &lt;p&gt;As I mentioned, to communicate between the Web role and worker role, I want to use &lt;a href="http://msdn.microsoft.com/en-us/library/dd179363.aspx"&gt;Azure queue storage&lt;/a&gt;.&amp;#160; Within the ASP.NET MVC Web role code (&lt;code&gt;RSVPController.cs&lt;/code&gt;), I added a call to a new method (line 12 below) to send an e-mail each time an RSVP is recorded.&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Register(&lt;span class="kwrd"&gt;string&lt;/span&gt; partitionKey)&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    Dinner dinner = dinnerRepository.&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        GetDinner(partitionKey);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!dinnerRepository.IsUserRegistered&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        (dinner, User.Identity.Name))&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        RSVP rsvp = &lt;span class="kwrd"&gt;new&lt;/span&gt; RSVP(dinner.PartitionKey, &lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            User.Identity.Name);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        dinnerRepository.AddRSVP(rsvp);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        dinnerRepository.Save();&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        SendRsvpEmail(dinner, rsvp);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; Content(&lt;span class="str"&gt;&amp;quot;Thanks - we'll see you there!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;}&lt;/pre&gt;
  &lt;/div&gt;
  &lt;style type="text/css"&gt;



































































.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Sending the e-mail” here really means putting a new message on a queue (one that my worker role is listening to).&amp;#160; Below is the implementation of &lt;code&gt;SendRsvpEmail&lt;/code&gt;.&amp;#160; The queue name I’ve selected here is ‘rsvps’, and the code for the first 10 lines or so is more or less boilerplate to get a handle to the queue and ensure it exists before posting messages to it.&lt;/p&gt;

  &lt;p&gt;&amp;#160;&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SendRsvpEmail(Dinner dinner, RSVP rsvp)&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    Boolean queueCreated = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    Boolean queueExists = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    QueueStorage queueStorage = QueueStorage.Create&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;      (StorageAccountInfo.&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;       GetDefaultQueueStorageAccountFromConfiguration());&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    MessageQueue queue = queueStorage.GetQueue(&lt;span class="str"&gt;&amp;quot;rsvps&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    queueCreated = queue.CreateQueue(&lt;span class="kwrd"&gt;out&lt;/span&gt; queueExists);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (queueCreated || queueExists)&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        String RsvpXml = &lt;span class="kwrd"&gt;new&lt;/span&gt; XDocument(&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;         &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;&amp;quot;Rsvp&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;           &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;&amp;quot;DinnerName&amp;quot;&lt;/span&gt;, dinner.Title),&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;           &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;&amp;quot;DinnerDate&amp;quot;&lt;/span&gt;, dinner.EventDate),&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;           &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;&amp;quot;Attendee&amp;quot;&lt;/span&gt;, rsvp.AttendeeName),&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;           &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;&amp;quot;HostName&amp;quot;&lt;/span&gt;, dinner.HostedBy),&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;           &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;&amp;quot;HostEmail&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;              membershipService.GetUserEmail(&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;                 dinner.HostedBy))&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;           )&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        ).ToString();&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;        queue.PutMessage(&lt;span class="kwrd"&gt;new&lt;/span&gt; Message(RsvpXml));&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;        RoleManager.WriteToLog(&lt;span class="str"&gt;&amp;quot;Information&amp;quot;&lt;/span&gt;, RsvpXml);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;   }&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;}&lt;/pre&gt;
  &lt;/div&gt;

  &lt;p&gt;The format of the message put in the queue is XML, and I used LINQ to XML to include the name of the dinner, the date, the attendee name, host, and the email of the host in the message (lines 13-23).&amp;#160; The message then gets put onto the queue in line 25 and logged in the next line.&lt;/p&gt;

  &lt;p&gt;On the other end, my worker role is polling for new messages on the ‘rsvps’ queue, and when it finds one, begins processing it.&amp;#160; Here’s the code extracted from the polling loop of my worker role.&amp;#160; It’s as simple as pulling the message off the queue, reconstituting it from the XML (I declare a simple &lt;code&gt;DinnerDetails&lt;/code&gt; data transfer object to hold the information), and then calling the method in the worker role that actually sends the e-mail via the SMTP client (&lt;code&gt;SendEMail&lt;/code&gt;).&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;Message msg = queue.GetMessage();&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (msg != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre class="alt"&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;span class="rem"&gt;// message should be an XML document&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    XDocument msgXml = XDocument.Parse(&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;      msg.ContentAsString());&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    RoleManager.WriteToLog(&lt;span class="str"&gt;&amp;quot;Information&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;      msgXml.ToString());&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="rem"&gt;// parse out dinner details from XML message&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    DinnerDetails rsvp = &lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;      (from m &lt;span class="kwrd"&gt;in&lt;/span&gt; msgXml.Descendants(&lt;span class="str"&gt;&amp;quot;Rsvp&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;      select &lt;span class="kwrd"&gt;new&lt;/span&gt; DinnerDetails()&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;           DinnerName = m.Element(&lt;span class="str"&gt;&amp;quot;DinnerName&amp;quot;&lt;/span&gt;).Value,&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;           DinnerDate = m.Element(&lt;span class="str"&gt;&amp;quot;DinnerDate&amp;quot;&lt;/span&gt;).Value,&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;           Attendee = m.Element(&lt;span class="str"&gt;&amp;quot;Attendee&amp;quot;&lt;/span&gt;).Value,&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;           HostName = m.Element(&lt;span class="str"&gt;&amp;quot;HostName&amp;quot;&lt;/span&gt;).Value,&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;           HostEmail = m.Element(&lt;span class="str"&gt;&amp;quot;HostEmail&amp;quot;&lt;/span&gt;).Value&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    ).FirstOrDefault();&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;    &lt;span class="rem"&gt;// send e-mail&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    SendEMail(rsvp);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;    &lt;span class="rem"&gt;// delete the message from the queue&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;    queue.DeleteMessage(msg);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;}&lt;/pre&gt;
  &lt;/div&gt;

  &lt;p&gt;Here’s the crux of the &lt;code&gt;SendEMail&lt;/code&gt; method; there’s a bit more error checking in &lt;a href="http://cid-cd719ef6510408a8.skydrive.live.com/self.aspx/Buffalo%20IT-Dev%20Day/Azure/NerdDinnerAzure.zip" target="_blank"&gt;the download&lt;/a&gt;.&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;SmtpClient client;&lt;/pre&gt;

    &lt;pre&gt;MailMessage message;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="rem"&gt;// set up SMTP Relay&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;client = &lt;span class="kwrd"&gt;new&lt;/span&gt; SmtpClient(SMTPHost, SMTPPort);&lt;/pre&gt;

    &lt;pre&gt;client.EnableSsl = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;client.Credentials = &lt;span class="kwrd"&gt;new&lt;/span&gt; NetworkCredential(&lt;/pre&gt;

    &lt;pre&gt;   SMTPAccount, SMTPPassword);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="rem"&gt;// populate new message&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;message = &lt;span class="kwrd"&gt;new&lt;/span&gt; MailMessage(&lt;/pre&gt;

    &lt;pre&gt;   &lt;span class="kwrd"&gt;new&lt;/span&gt; MailAddress(&lt;span class="str"&gt;&amp;quot;rsvp@nerdbytes.net&amp;quot;&lt;/span&gt;), &lt;/pre&gt;

    &lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;new&lt;/span&gt; MailAddress(rsvp.HostEmail));&lt;/pre&gt;

    &lt;pre&gt;message.Subject = &lt;span class="str"&gt;&amp;quot;NerdBytes RSVP&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;message.Body = rsvp.HostName + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; +&lt;/pre&gt;

    &lt;pre&gt;    Environment.NewLine + Environment.NewLine +&lt;/pre&gt;

    &lt;pre class="alt"&gt;    rsvp.Attendee + &lt;span class="str"&gt;&amp;quot; has RSVP'd for '&amp;quot;&lt;/span&gt; + &lt;/pre&gt;

    &lt;pre&gt;    rsvp.DinnerName + &lt;span class="str"&gt;&amp;quot;' on &amp;quot;&lt;/span&gt; +&lt;/pre&gt;

    &lt;pre class="alt"&gt;    DateTime.Parse(rsvp.DinnerDate).ToShortDateString() +&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="str"&gt;&amp;quot; at &amp;quot;&lt;/span&gt; +   &lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&amp;#160;&amp;#160; DateTime.Parse(rsvp.DinnerDate).ToShortTimeString();&lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Now, in order to get the host's email address, I modified the Dinners controller (&lt;code&gt;DinnersController.cs&lt;/code&gt; in the ASP.NET MVC application/Web role) as well, so that the &lt;code&gt;IMembershipService&lt;/code&gt; was dependency-injected along with the Dinner repository service.&amp;#160; That necessitated a few additional code changes in the original port that Michael did.&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DinnersController : Controller {&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    IDinnerRepository dinnerRepository;&lt;/pre&gt;

    &lt;pre&gt;    IMembershipService membershipService;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;// Dependency Injection enabled constructors&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; DinnersController()&lt;/pre&gt;

    &lt;pre&gt;        : &lt;span class="kwrd"&gt;this&lt;/span&gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; DinnerRepository(),&lt;/pre&gt;

    &lt;pre class="alt"&gt;               &lt;span class="kwrd"&gt;new&lt;/span&gt; AccountMembershipService())&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; DinnersController(IDinnerRepository repository,&lt;/pre&gt;

    &lt;pre&gt;       IMembershipService membership)&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        dinnerRepository = repository;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        membershipService = membership;&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;
  &lt;/div&gt;

  &lt;p&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that was pretty much it.&amp;#160; Note, if you’re following along, the &lt;a href="http://nerddinner.codeplex.com/" target="_blank"&gt;NerdDinner project on CodePlex&lt;/a&gt; has advanced a bit since Michael worked on his port to Azure, so code may look a bit different, but the approach is the same.&lt;/p&gt;

&lt;p&gt;The other, and pretty major, thing to note is that all the work he did to set up Azure storage will largely be unnecessary once &lt;a href="http://www.microsoft.com/azure/sql.mspx" target="_blank"&gt;SQL Azure&lt;/a&gt; is available (late summer).&amp;#160; SQL Azure is essentially SQL Server in the cloud, and would allow me to store the NerdDinner data (and the ASP.NET membership database) in the cloud in the same relational format that the original authors used.&amp;#160; That alone would probably have cut out 2/3rds of the work (or more) for the original port to Azure.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Mobilizing NerdBytes&lt;/h1&gt;

&lt;p&gt;But there’s more… My other session at the &lt;a href="http://blogs.msdn.com/jimoneil/archive/2009/06/02/greater-buffalo-it-dev-day-july-21st.aspx" target="_blank"&gt;Greater Buffalo IT/Dev Day&lt;/a&gt; was on &lt;a href="http://cid-cd719ef6510408a8.skydrive.live.com/browse.aspx/Buffalo%20IT-Dev%20Day/Mobile" target="_blank"&gt;Windows Mobile Development&lt;/a&gt;.&amp;#160; While I spent most of the time there talking about and building Compact Framework applications, I wanted to touch on mobile for the web as well – including new features in “IE6 on 6”, widgets, and Silverlight.&amp;#160; For the IE6 aspect, what better way to show the features than the cloud adaptation of NerdDinner.&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 0px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Desktop mode" border="0" alt="Desktop mode" align="right" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/NerdDinnerOnAzureTake2_E155/image_5.png" width="180" height="240" /&gt; As you may know, Mobile IE has a Desktop and a Mobile rendering mode option.&amp;#160; When using the Desktop mode, Mobile IE sends the same user-agent string as the desktop version of IE, so you get a display something like that on the right – functional but not optimal for the device’s form factor.&lt;/p&gt;

&lt;p&gt;To improve the user experience, we need to introduce a different user-interface for those on mobile devices, one triggered by the “Mobile” mode of IE.&amp;#160; That’s where &lt;a href="http://www.hanselman.com/blog/MixMobileWebSitesWithASPNETMVCAndTheMobileBrowserDefinitionFile.aspx" target="_blank"&gt;this post by Scott Hanselman&lt;/a&gt; comes in.&amp;#160; He’d already done the work and checked it in… alas to a build that was &lt;em&gt;after&lt;/em&gt; what Michael had ported to Azure (which was my starting point).&amp;#160; Since I was committed to the Azure port, I &lt;strike&gt;cobbled together&lt;/strike&gt; incorporated Scott’s work to my existing code base, so what you get in the &lt;a href="http://cid-cd719ef6510408a8.skydrive.live.com/self.aspx/Buffalo%20IT-Dev%20Day/Azure/NerdDinnerAzure.zip"&gt;download&lt;/a&gt; is not quite what he blogged about.. but close.&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="514"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="133"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="NerdBytes home" border="0" alt="NerdBytes home" align="left" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/NerdDinnerOnAzureTake2_E155/image_8.png" width="133" height="177" /&gt;&lt;/td&gt;

      &lt;td valign="top" width="146"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="NerdBytes list" border="0" alt="NerdBytes list" align="left" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/NerdDinnerOnAzureTake2_E155/image_11.png" width="133" height="177" /&gt;&lt;/td&gt;

      &lt;td valign="top" width="233"&gt;
        &lt;br /&gt;To the left are a few screens from the mobile views of my NerdBytes&amp;#160; ASP.NET MVC application.&amp;#160; &lt;a href="http://www.hanselman.com/blog/MixMobileWebSitesWithASPNETMVCAndTheMobileBrowserDefinitionFile.aspx"&gt;Scott goes into details&lt;/a&gt; on the implementation, but it was cool to see how for the most part all that was affected in the implementation was the views, another testament to the separation-of-concerns philosophy espoused by ASP.NET MVC.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;By the way, I wandered on to a very helpful utility when doing the work with the mobile device.&amp;#160; Since my application was deployed to the cloud, waiting for the deployment (which can take several minutes) to see what the site looked like wasn’t very productive.&amp;#160; &lt;a href="http://www.enhanceie.com/ietoys/uapick.asp" target="_blank"&gt;Bayden UAPick&lt;/a&gt; is a very cool IE add-on that allows you to modify what user-agent string is sent by the browser.&amp;#160; So, for testing I could work with my Azure Development Fabric on my laptop and test with IE8, but use UAPick (which installs itself in IE as a menu item under Tools) to spoof the user-agent string sent by a mobile device (or other browsers for that matter) – like this:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="IE8 with Mobile UA String" border="0" alt="IE8 with Mobile UA String" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/NerdDinnerOnAzureTake2_E155/image_16.png" width="407" height="325" /&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Well, that pretty much covers how I got to where I did.&amp;#160; &lt;a href="http://nerdbytes.cloudapp.net/"&gt;NerdBytes&lt;/a&gt; is live now, so if you want to test it out while looking over the code, feel free.&amp;#160; Or load it up yourself in your own little spot in the cloud – Windows Azure is still in CTP, and more importantly FREE!, until &lt;a href="http://www.microsoftpdc.com/" target="_blank"&gt;PDC&lt;/a&gt; in November.&amp;#160; Also, drop me a line if you’re running into trouble, I undoubtedly left out some critical detail in my overview here!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9848506" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Azure/default.aspx">Azure</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Windows+Mobile/default.aspx">Windows Mobile</category></item><item><title>M-V-C is H-E-R-E</title><link>http://blogs.msdn.com/jimoneil/archive/2009/03/18/m-v-c-is-h-e-r-e.aspx</link><pubDate>Wed, 18 Mar 2009 20:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9485667</guid><dc:creator>joneil</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/9485667.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=9485667</wfw:commentRss><description>&lt;p&gt;Here’s one of a number of cool announcements coming out of &lt;a href="http://2009.visitmix.com/"&gt;MIX 09&lt;/a&gt; going on now at the Venetian in Las Vegas.&amp;#160; The ASP.NET MVC (Model-View-Controller) Framework version 1.0 is now live.&amp;#160; This is the culmination of a pretty amazing exercise in transparent development in which multiple previews and release candidates were made available to the community, and an active dialog was maintained on the &lt;a href="http://www.asp.net/mvc"&gt;ASP.NET Web Site&lt;/a&gt; as well as by key bloggers &lt;a href="http://www.amazon.com/gp/product/0470384611?ie=UTF8&amp;amp;tag=scoblo04-20&amp;amp;linkCode=xm2&amp;amp;camp=1789&amp;amp;creativeASIN=0470384611"&gt;&lt;img style="border-right-width: 0px; margin: 10px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Professional ASP.NET MVC" border="0" alt="Professional ASP.NET MVC" align="right" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/MVCisHERE_12737/image_3.png" width="89" height="112" /&gt;&lt;/a&gt;like &lt;a href="http://www.haacked.com"&gt;Phil Haack&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/scottgu"&gt;Scott Guthrie&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;If you didn’t have the chance to be part of the evolution of ASP.NET MVC, there’s a great set of tutorial resources on the &lt;a href="http://www.asp.net/mvc/"&gt;ASP.NET Web Site&lt;/a&gt;, including a training kit.&amp;#160; There’s also a &lt;strong&gt;&lt;a href="http://aspnetmvcbook.s3.amazonaws.com/aspnetmvc-nerdinner_v1.pdf"&gt;free e-book tutorial&lt;/a&gt;&lt;/strong&gt; authored by Scott Guthrie.&amp;#160; This 185-page, soup-to-nuts walkthrough is actually chapter 1 of an upcoming book from Wrox Press: &lt;em&gt;&lt;a href="http://www.amazon.com/gp/product/0470384611?ie=UTF8&amp;amp;tag=scoblo04-20&amp;amp;linkCode=xm2&amp;amp;camp=1789&amp;amp;creativeASIN=0470384611"&gt;Professional ASP.NET MVC 1.0&lt;/a&gt;&lt;/em&gt; (with co-authors &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/a&gt;, &lt;a href="http://blog.wekeroad.com/"&gt;Rob Conery&lt;/a&gt;, and &lt;a href="http://www.haacked.com"&gt;Phil Haack&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://aspnetmvcbook.s3.amazonaws.com/aspnetmvc-nerdinner_v1.pdf"&gt;&lt;strong&gt;Download the e-book tutorial&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I just stumbled across the &lt;a href="http://girldeveloper.com/waxing-dev/asp-net-mvc-translated-for-the-web-forms-programmer-1-in-a-series/"&gt;first of a series of blog posts&lt;/a&gt; by Sara Chipps on MVC for the Web Forms programmer.&amp;#160; She does a great job of&amp;#160; ‘translating’ between the two technologies, which should help ease the anxiety!&amp;#160; Keep an eye on her blog as you start exploring ASP.NET MVC.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9485667" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MIX/default.aspx">MIX</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>TONIGHT! Inaugural Meeting of ASP.NET Professionals</title><link>http://blogs.msdn.com/jimoneil/archive/2009/03/16/tonight-inaugural-meeting-of-asp-net-professionals.aspx</link><pubDate>Mon, 16 Mar 2009 16:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9479482</guid><dc:creator>joneil</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/9479482.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=9479482</wfw:commentRss><description>&lt;p&gt;Quick reminder: the first meeting of the newly formed &lt;a href="http://neasp.net"&gt;ASP.NET Professionals User Group&lt;/a&gt; takes place tonight at the Microsoft office at 201 Jones Road in Waltham.&amp;#160; The meeting runs from 6:15 to 8:30.&amp;#160; Regular meetings will occur on the 4th Tuesday of each month.&lt;/p&gt;  &lt;p&gt;Kicking off the new group tonight will be &lt;a href="http://neasp.net/Default.aspx"&gt;Fritz Onion speaking&lt;/a&gt; on &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;The Changing Face of ASP.NET Development&lt;/strong&gt; &lt;/p&gt;    &lt;p&gt;Ajax, MVC, jQuery, DynamicData - things you should know before you start your next ASP.NET project.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/TONIGHTInauguralMeeting.NETProfessionals_C8D7/image_3.png" width="514" height="79" /&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9479482" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/User+Group/default.aspx">User Group</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Massachusetts/default.aspx">Massachusetts</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Get into the MIX09</title><link>http://blogs.msdn.com/jimoneil/archive/2009/03/04/get-into-the-mix09.aspx</link><pubDate>Wed, 04 Mar 2009 18:43:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9458609</guid><dc:creator>joneil</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/9458609.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=9458609</wfw:commentRss><description>&lt;p&gt;It’s exactly two weeks until &lt;a href="http://2009.visitmix.com/"&gt;MIX09&lt;/a&gt;, and here’s the scene from my home office window juxtaposed with one of the MIX09 venue.&amp;#160; Vegas is looking pretty good, huh?&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="5" align="center"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://www.weather.com/weather/local/01720"&gt;&lt;img style="border-right-width: 0px; margin: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Will Winter never end?" border="0" alt="Will Winter never end?" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/GetintotheMIX09_96D1/DSCN0843_1.jpg" width="180" height="240" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;a href="http://www.venetian.com/"&gt;&lt;img style="border-right-width: 0px; margin: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="O solo mio!" border="0" alt="O solo mio!" src="http://newton.typepad.com/content/images/2007/03/23/venetian.jpg" width="288" height="237" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Weather aside, there’s a lot of other great things in store at this year’s edition of *the* conference focused on next generation web, rich internet applications, and the collaboration between developers and designers.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://2009.visitmix.com/"&gt;&lt;img style="border-right-width: 0px; margin: 0px 15px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/GetintotheMIX09_96D1/image_3.png" width="240" height="54" /&gt;&lt;/a&gt; There’s nearly &lt;a href="https://content.visitmix.com/2009/sessions/?categories=Silverlight"&gt;30 sessions on Silverlight&lt;/a&gt; alone, including not one, not two, but three on what’s in store with Silverlight 3.&amp;#160; There’s quite a few on ASP.NET MVC as well (for which &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=ee4b2e97-8a72-449a-82d2-2f720d421031&amp;amp;displaylang=en"&gt;RC2 was made available&lt;/a&gt; last night).&amp;#160; Add to that Azure, Live Services, UI/UX, and you’ve got about &lt;a href="https://content.visitmix.com/2009/sessions/"&gt;10 dozen sessions&lt;/a&gt; to choose from.&lt;/p&gt;  &lt;p&gt;Check out the MIX09 site and schedule your &lt;strike&gt;vacation&lt;/strike&gt; training now!&amp;#160; And if you can’t be there, join Chris, Bob, and me on the &lt;a href="http://blogs.msdn.com/jimoneil/archive/2009/02/16/northeast-roadshow-march-madness-edition.aspx"&gt;Northeast Roadshow&lt;/a&gt;.&amp;#160; We’ll actually be in Hartford and Augusta while MIX is going on.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9458609" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MIX/default.aspx">MIX</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>ASP.NET MVC Release Candidate 2</title><link>http://blogs.msdn.com/jimoneil/archive/2009/03/03/asp-net-mvc-release-candidate-2.aspx</link><pubDate>Wed, 04 Mar 2009 06:22:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9457922</guid><dc:creator>joneil</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/9457922.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=9457922</wfw:commentRss><description>&lt;p&gt;Hot of the wire(less)… &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=ee4b2e97-8a72-449a-82d2-2f720d421031&amp;amp;displaylang=en"&gt;Release Candidate 2 of the ASP.NET Model View Controller (MVC)&lt;/a&gt; framework is now available.&amp;#160; This brings the technology, which provides an alternative methodology for building ASP.NET web sites, one step closer to release.&amp;#160; ASP.NET MVC builds off of the .NET Framework 3.5 SP1 and requires Visual Studio 2008 SP1 or Visual Studio Web Developer 2008 SP1 to get the complete development experience.&lt;/p&gt;  &lt;p&gt;If you haven’t had a chance yet to see what ASP.NET MVC is all about, there’s also a great set of tutorials, videos, and sample applications at the &lt;a href="http://www.asp.net/mvc/"&gt;ASP.NET MVC site&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9457922" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>I’ll have an RC</title><link>http://blogs.msdn.com/jimoneil/archive/2009/01/27/i-ll-have-an-rc.aspx</link><pubDate>Wed, 28 Jan 2009 01:13:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9378733</guid><dc:creator>joneil</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/9378733.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=9378733</wfw:commentRss><description>&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 0px 25px 15px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="rc" border="0" alt="rc" align="left" src="http://blogs.msdn.com/blogfiles/jimoneil/WindowsLiveWriter/IllhaveanRC_F21A/rc_3.gif" width="146" height="89" /&gt;When I was growing up in the South, “RC” meant one thing – &lt;a href="http://www.rccolainternational.com/"&gt;Royal Crown Cola&lt;/a&gt;.&amp;#160; It’s still around, but certainly RC has a much different connotation in the&amp;#160; technology circles that I’m now part of.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;It’s that latter interpretation -- “Release Candidate” -- that has prompted this latest post. Just this week, two significant products have just released their RC 1.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/windows/internet-explorer/beta/"&gt;Internet Explorer 8 RC1&lt;/a&gt; is now available for users of XP, Vista, and Windows Server (2003 and 2008).&amp;#160; If you are running Windows 7, you’ll need to work with the version of IE 8 that shipped with the beta;&amp;#160; IE 8 on Windows 7 will be refreshed on a separate schedule.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://www.asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt; Release Candidate is also now available (&lt;a href="http://go.microsoft.com/fwlink/?LinkID=141184&amp;amp;clcid=0x409"&gt;download the MSI&lt;/a&gt;), and will be the last release prior to “version 1.0” expected next month.&amp;#160; Both &lt;a href="http://www.haacked.com/archive/2009/01/27/aspnetmvc-release-candidate.aspx"&gt;Phil Haack&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/01/27/asp-net-mvc-1-0-release-candidate-now-available.aspx"&gt;Scott Guthrie&lt;/a&gt; have loads of information on their respective blogs.&amp;#160; (You may want to check out Phil’s &lt;a href="http://haacked.com/archive/2009/01/27/controls-collection-cannot-be-modified-issue-with-asp.net-mvc-rc1.aspx"&gt;subsequent post&lt;/a&gt; as well where he documents a known bug with the RC – just to save yourself sometime pulling your own hair out!).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9378733" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/IE8/default.aspx">IE8</category></item><item><title>Dynamic Data Just Got Cooler</title><link>http://blogs.msdn.com/jimoneil/archive/2008/07/25/dynamic-data-just-got-cooler.aspx</link><pubDate>Sat, 26 Jul 2008 04:13:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8773677</guid><dc:creator>joneil</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/8773677.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=8773677</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/scothu/archive/2008/07/21/many-updates-on-dynamic-data.aspx"&gt;Scott Hunter&lt;/a&gt;, the Program Manager for ASP.NET Dynamic Data, announced the Dynamic Data for MVC Preview available on &lt;a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=15459"&gt;CodePlex&lt;/a&gt;.&amp;nbsp; This takes the powerful scaffolding and data validation models that we see applied to Web Form applications in .NET 3.5 SP1 to the MVC framework.&amp;nbsp; Note it's a very early preview so is not as functional as the Web Forms version is today, but it's an exciting step nonetheless.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8773677" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category></item><item><title>Constraints in ASP.NET Routing</title><link>http://blogs.msdn.com/jimoneil/archive/2008/07/07/constraints-in-asp-net-routing.aspx</link><pubDate>Tue, 08 Jul 2008 00:36:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8704288</guid><dc:creator>joneil</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jimoneil/comments/8704288.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jimoneil/commentrss.aspx?PostID=8704288</wfw:commentRss><description>&lt;p&gt;ASP.NET routing is a new feature incorporated in the upcoming .NET 3.5 Service Pack 1 release.&amp;nbsp; While closely associated with the implementation of &lt;a href="http://www.asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt; (Model-View-Controller), it's really a separate piece of functionality consolidated in two assemblies&lt;/p&gt; &lt;ul&gt; &lt;li&gt;System.Web.Routing, and&amp;nbsp; &lt;li&gt;System.Web.Abstractions&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I've been looking at routing recently as part of &lt;a href="http://www.asp.net/dynamicdata"&gt;ASP.NET Dynamic Data&lt;/a&gt;, and soon found myself intrigued by the various permutations you can cook up.&amp;nbsp; While there are quite a few &lt;a href="http://msmvps.com/blogs/luisabreu/archive/2008/07/04/the-routing-series.aspx"&gt;blog posts&lt;/a&gt; and&amp;nbsp; &lt;a href="http://quickstarts.asp.net/3-5-extensions/mvc/ASPNETRouting.aspx"&gt;tutorials&lt;/a&gt; on the routing feature, I haven't found many (yet) that talk much about the new constraint capabilities introduced in &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=92F2A8F0-9243-4697-8F9A-FCF6BC9F66AB&amp;amp;displaylang=en"&gt;ASP.NET MVC Preview 3&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;In a nutshell, ASP.NET routing allows you to set up a RouteTable consisting of URL 'templates' against which the System.Web.UrlRoutingModule (referenced in web.config) compares each requested URL to see if there is a match.&amp;nbsp; If there is, the HTTP request is handed off to a specific implementation of an IHttpHandler for servicing.&amp;nbsp; ASP.NET MVC comes with its own implementation of an IHttpHandler (System.Web.Mvc.MvcRouteHandler), but where's the fun in that... so that's when I decided to try my own hand.&lt;/p&gt; &lt;p&gt;As I mentioned, each route is really a template. For instance, a URL of &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;dayinhistory/{year}/{month}/{day} &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;would match things like&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;http://mysite.com/dayinhistory/2000/1/1&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;and assign values to "year", "month", and "day" in a Values collection that can be accessed within the route handler.&amp;nbsp; Unfortunately, it would also match URLs like&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;http://mysite.com/dayinhistory/red/sox/rock&lt;/p&gt; &lt;p&gt;http://mysite.com/dayinhistory/2000/56/40&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;neither of which represents a valid date.&lt;/p&gt; &lt;p&gt;While each route definition can be initialized with a collection of Constraints, prior to ASP.NET MVC Preview 3, the constraint itself could only be a string representing a regular expression.&amp;nbsp; That works for some scenarios, but it doesn't really help when you have more complex validation, such as date checking. &lt;/p&gt; &lt;p&gt;With Preview 3, a new interface, IRouteConstraint, was added to System.Web.Routing and vastly expands your constraint-checking capabilities.&amp;nbsp; Now you can specify a constraint not only as string (to be interpreted as a regular expression, as in the past) but also as a custom class implementing this new interface.&amp;nbsp; IRouteConstraint mandates implementation of a Match method, within which you can do pretty much anything and then simply return true if the validation succeeds or false if it fails.&amp;nbsp; &lt;/p&gt; &lt;p&gt;As you can see from the Match signature below, you have access to the selected route, the substituted URL parameters, and the HTTP context object to perform the validation.&amp;nbsp; The routeDirection parameter is an enumeration that tells you whether the method is executing on an 'incoming' basis, that is the UrlRoutingModule is trying to find a match for a requested URL, or on an 'outgoing' basis, in which you're requesting a URL to be created to match a route - generally in response to invoking GetVirtualPath to build URLs for links within your own pages.&lt;/p&gt; &lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Match(HttpContextBase httpContext, Route route, 
     &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; parameterName, RouteValueDictionary values, RouteDirection routeDirection)
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;As an example, here's a simple class I created to validate the date URL pattern mentioned above.&amp;nbsp; It simply tries to create a date from the parameter values extracted from the URL, and if that fails (i.e., an exception is thrown), the validation fails.&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; DateConstraintValidator : IRouteConstraint
{
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Match(HttpContextBase httpContext, Route route, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; parameterName, 
                      RouteValueDictionary values, RouteDirection routeDirection)
    {
        &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
        {
            DateTime potentialDate = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(
                Int32.Parse(values[&lt;span style="color: #006080"&gt;"year"&lt;/span&gt;].ToString()), 
                Int32.Parse(values[&lt;span style="color: #006080"&gt;"month"&lt;/span&gt;].ToString()), 
                Int32.Parse(values[&lt;span style="color: #006080"&gt;"day"&lt;/span&gt;].ToString()));
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
        }
        &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception)
        {
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
        }
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now, my route definition in global.asax looks like this (DateUrlRouter is my custom IHttpHandler that instantiates a single ASPX page to display the date in a Calendar control):&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Route r = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Route(&lt;span style="color: #006080"&gt;"dayinhistory/{year}/{month}/{day}"&lt;/span&gt;, 
    &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,                
    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RouteValueDictionary { {&lt;span style="color: #006080"&gt;"year"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateConstraintValidator()} }, 
    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateUrlRouter());
routes.Add(r);&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;While I only have one constraint on "year", that's really enough, because the Match method has access to all of the substituted values as one of its parameters.&amp;nbsp; (Actually, it doesn't really matter what value is supplied for the string "year" here, since the constraint reference will come along for the ride anyway!)&lt;/p&gt;
&lt;p&gt;If you're interested in seeing this all in action, check out my sample on Skydrive:&lt;/p&gt;&lt;iframe style="border-right: #dde5e9 1px solid; padding-right: 0px; border-top: #dde5e9 1px solid; padding-left: 0px; padding-bottom: 0px; margin: 3px; border-left: #dde5e9 1px solid; width: 240px; padding-top: 0px; border-bottom: #dde5e9 1px solid; height: 66px; background-color: #ffffff" marginwidth="0" marginheight="0" src="http://cid-cd719ef6510408a8.skydrive.live.com/embedrowdetail.aspx/Public/Blog/20080707|_routing.zip" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8704288" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jimoneil/archive/tags/Dynamic+Data/default.aspx">Dynamic Data</category><category domain="http://blogs.msdn.com/jimoneil/archive/tags/MVC/default.aspx">MVC</category></item></channel></rss>