<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Aaron Lerch &#187; asp.net mvc</title>
	<atom:link href="http://www.aaronlerch.com/blog/category/aspnet-mvc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.aaronlerch.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 10 Mar 2010 12:45:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Run ASP.NET MVC on Windows Azure</title>
		<link>http://www.aaronlerch.com/blog/2008/11/01/run-aspnet-mvc-on-windows-azure/</link>
		<comments>http://www.aaronlerch.com/blog/2008/11/01/run-aspnet-mvc-on-windows-azure/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 05:23:31 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[azure]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/11/01/run-aspnet-mvc-on-windows-azure/</guid>
		<description><![CDATA[If you’ve purposefully been ignoring the announcements out of PDC, I don’t blame you one bit. Everybody knew it would be the unveiling of Microsoft’s “cloud computing” initiative, and just about the only thing we didn’t know was the official name of it: Windows Azure. And of course I pronounce it wrong every time (I [...]]]></description>
			<content:encoded><![CDATA[<p>If you’ve purposefully been ignoring the announcements out of PDC, I don’t blame you one bit. Everybody knew it would be the unveiling of Microsoft’s “cloud computing” initiative, and just about the only thing we didn’t know was the official name of it: Windows Azure. And of course I pronounce it wrong every time (I say “ah-<em>jour</em>”, as in “soup-de-jour”). It’s hard to call it “initiative” when they’re the 3rd one to bring a product to the table. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>One thing I was looking forward to was hearing about the ASP.NET MVC story on Azure. So color me surprised when I found out there wasn’t one. Since ASP.NET MVC is bin-deployable it shouldn’t be impossible, and doing some quick searches didn’t retrieve any results showing anybody else having tried this. Of course <em>later</em> I discovered that Phil and Eilon had whipped up a sample app that ran ASP.NET MVC on Azure, but was pleased to find out that the <a href="http://blogs.msdn.com/jnak/archive/2008/10/28/asp-net-mvc-projects-running-on-windows-azure.aspx">downloadable sample app</a> didn’t work. In fact, it seemed to just be MVC stuff slapped into a WebRole project. (I’m guessing something got “lost in translation” since it wasn’t Phil or Eilon that posted the code.)</p>
<p>Anyway, here’s how you can get ASP.NET MVC up and running on Azure. I’ve created a Visual Studio template for this to make it easy to set up &#8211; <a href="http://s3.amazonaws.com:80/aaronlerch.com/files/ASP_NET_MVC_Web_Role.zip"><strong>download it here</strong></a>. To avoid distributing code that isn’t my own (i.e. Windows Azure SDK Samples) there are a few steps you’ll have to take. I’m presuming that you’ve already installed the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=BB893FB0-AD04-4FE8-BB04-0C5E4278D3E9&amp;displaylang=en">Windows Azure SDK</a> and the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=63D0D248-1B08-4F7D-ABDE-62EB75CB1E69&amp;displaylang=en">Azure Visual Studio tools</a>.</p>
<p>One thing that running a web application “in the cloud” means is that you can instantly scale higher by adding more “instances”. This means the leaky-as-a-sieve abstraction of “session state” isn’t immediately available (finally!) since any given HTTP request could be going to a different server. The default session state provider for ASP.NET is an in-memory provider. This assumes that every request comes to the same physical machine. Session state providers have varied in their reliability and handling of scalability, but the other built-in providers include an out-of-proc provider (still same machine, but more resilient to IIS going up and down) and a SQL Server provider. None of these are enabled on the Azure platform, for good reason.</p>
<p>The limitation of zero session state wouldn’t matter except that ASP.NET MVC includes the concept of “Temp Data”, which is data persisted in one request and made available to <em>the next request only</em>. By default, MVC uses the session to store this data.</p>
<p><em>Aside: like it does everywhere else, ASP.NET MVC allows you to swap out default implementations for TempData persistence. A better solution than what I have below is to specifically implement a TempDataProvider that uses the Azure data storage capabilities. Look for that soon. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </em></p>
<p>Fortunately for us the Windows Azure SDK includes some “samples”, including full implementations of membership, profile, and session providers built on the Azure data storage platform. So let’s hack those in to fulfill the default requirements of ASP.NET MVC. The only thing that I’ll say about this is that much of this stuff had better be baked into the SDK/platform by the time it goes GA. This is just a CTP, and Microsoft has been doing better at earlier community releases, so I’ll cut them some slack. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  But this is <strong>way</strong> to much work to be a reasonable shipped solution.</p>
<h4>Unzip the “samples.zip” file in the Azure SDK and build the “AspProviders” application.</h4>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_sample_location.png" /></p>
<p>They’ve conveniently included “buildme.cmd” batch files, but I built the application using Visual Studio since I like to see more of “what’s going on” (even though I really don’t see more, per se).</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_build_sample.png" /></p>
<h4>Create the required tables in the Azure Development Storage.</h4>
<p>Open the Azure SDK command prompt under your start menu, and navigate to the directory containing the AspProviders output. Run the command “devtablegen” passing in the assembly name “AspProviders.dll”. This command creates the appropriate database structures to persist objects that meet certain criteria. Run devtablegen with no parameters for a short description, or check out the documentation for more info as well.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_devtablegen.png" /></p>
<p>You’ll get a confirmation window that displays progress and shows that the table was created successfully.</p>
<h4>Start the Development Storage service.</h4>
<p>By now, the storage service should be running, but you’ll need to explicitly enable its endpoints. Open the UI from the system tray icon (<img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_development_storage_icon.png" />), and click “Start”. If you’ve never started it before, it will ask you for the name of the database – select “AspProviders”.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_development_storage.png" /></p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_database_selection.png" /></p>
<h4>Create a new Cloud Service and add an “ASP.NET MVC Web Role” project.</h4>
<p><a href="http://s3.amazonaws.com:80/aaronlerch.com/files/ASP_NET_MVC_Web_Role.zip"><strong>Download the Visual Studio template I created here.</strong></a> Import the template by copying the downloaded .zip file to “My Documents\Visual Studio 2008\Templates\Project Templates” (or whatever you have specified in Tools – Options – Projects and Solutions – General). Create a new “Blank Cloud Service” project.</p>
<p>&#160;<img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_cloud_service.png" /></p>
<p>Add a new “ASP.NET MVC Web Role” project using the installed template.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_web_role.png" /></p>
<p>Your VS solution should now approximate this:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_project_layout.png" /></p>
<p>Under the “Cloud Service” project, right-click on the “Roles” folder and select “Add &gt; Web Role Project in solution…” and select the web role project we just added.</p>
<h4>Cleanup</h4>
<p>Because I can’t distribute the compiled version of the sample app, and because the location of it on your drive depends entirely on your personal preferences, you’ll have to re-add the references manually. From the ASP.NET MVC Web Role project we added, delete the references to AspProviders and StorageClient</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_references.png" /></p>
<p>and re-add the references pointing to the assemblies we built above.</p>
<p>Press F5, and you’re up and running the default ASP.NET MVC sample app on the Windows Azure platform! From there the sky’s the limit. Or maybe “the cloud’s the limit”?</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/asp_net_azure_final.png" /></p>
<div class="wlWriterEditableSmartContent" id="scid:C16BAC14-9A3D-4c50-9394-FBFEF7A93539:9393a903-6e50-4089-877b-3a9699fc7c80" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><a href="http://www.dotnetkicks.com/kick/?url=http://www.aaronlerch.com/blog/2008/11/01/run-aspnet-mvc-on-windows-azure/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.aaronlerch.com/blog/2008/11/01/run-aspnet-mvc-on-windows-azure/" border="0" alt="kick it on DotNetKicks.com" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/11/01/run-aspnet-mvc-on-windows-azure/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Indy Tech Fest Slides</title>
		<link>http://www.aaronlerch.com/blog/2008/10/06/indy-tech-fest-slides/</link>
		<comments>http://www.aaronlerch.com/blog/2008/10/06/indy-tech-fest-slides/#comments</comments>
		<pubDate>Mon, 06 Oct 2008 06:06:37 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[community]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/10/06/indy-tech-fest-slides/</guid>
		<description><![CDATA[I really enjoyed giving my talk on ASP.NET MVC at Indy Tech Fest this year. Thanks to all who came! I think there were 75-100 people there.
A poll at the beginning showed that most people in attendance had done some sort of web development, about a third had done ASP.NET development, and 2 people had [...]]]></description>
			<content:encoded><![CDATA[<p>I really enjoyed giving my talk on ASP.NET MVC at Indy Tech Fest this year. Thanks to all who came! I think there were 75-100 people there.</p>
<p>A poll at the beginning showed that most people in attendance had done some sort of web development, about a third had done ASP.NET development, and 2 people had worked with ASP.NET MVC. The most challenging thing was that almost everybody was unfamiliar with the MVC pattern. And yet again I learned the difference between a master and a wanna-be. A master can take complex principles and concepts and express them in a simple form that people can immediately understand. I, on the other hand, cannot. I seemed to struggle with getting the “core concepts” of ASP.NET MVC across in a way that was clear and unambiguous.</p>
<p>I’ve created a slideshare presentation with the slides. It’s an overview, and I only had time to cover a few aspects of it, but I’m still sure I was off on a few concepts – if you notice something, leave a comment so I can learn!</p>
<div id="__ss_638175" style="width: 425px; text-align: left"><a title="Indy Tech Fest 2008 - ASP.NET MVC" style="display: block; margin: 12px 0px 3px; font: 14px helvetica,arial,sans-serif; text-decoration: underline" href="http://www.slideshare.net/aaronlerch/indy-tech-fest-2008-aspnet-mvc-presentation?type=powerpoint">Indy Tech Fest 2008 &#8211; ASP.NET MVC</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=indytechfest-2008-aspnet-mvc-published-1223261777987020-9&amp;stripped_title=indy-tech-fest-2008-aspnet-mvc-presentation" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=indytechfest-2008-aspnet-mvc-published-1223261777987020-9&amp;stripped_title=indy-tech-fest-2008-aspnet-mvc-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p>Here links to various MVC resources to get you started with ASP.NET MVC:</p>
<p>- <a href="http://www.codeplex.com/aspnet"><strong>Download ASP.NET MVC from Codeplex</strong></a>     <br />- <a href="http://mvccontrib.com/"><strong>MVCContrib – community contributions/extensions to ASP.NET MVC</strong></a>     <br />- <a href="http://codecampserver.com/"><strong>CodeCampServer – a slightly-out-of-date-but-still-good reference implementation</strong></a>     <br />- <a href="http://www.asp.net/mvc/">Official ASP.NET MVC site (lots of links to resources)</a>     <br />- <a href="http://forums.asp.net/1146.aspx">ASP.NET MVC Forums – a lot of questions asked and answers given</a>     <br />- <a href="http://weblogs.asp.net/scottgu/archive/tags/MVC/default.aspx">ScottGu’s MVC posts</a>     <br />- <a href="http://haacked.com/">Phil Haack is the ASP.NET MVC Program Manager</a>     <br />- <a href="http://weblogs.asp.net/stephenwalther/archive/tags/ASP.NET+MVC/default.aspx">Stephen Walther has done many posts on ASP.NET MVC</a>     <br />- <a href="http://technorati.com/tag/aspnetmvc">Blog posts tagged “aspnetmvc” on Technorati</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/10/06/indy-tech-fest-slides/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rock the iPhone with ASP.NET MVC</title>
		<link>http://www.aaronlerch.com/blog/2008/06/08/rock-the-iphone-with-aspnet-mvc/</link>
		<comments>http://www.aaronlerch.com/blog/2008/06/08/rock-the-iphone-with-aspnet-mvc/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 23:30:06 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/06/08/rock-the-iphone-with-aspnet-mvc/</guid>
		<description><![CDATA[With much fanfare Apple announced the availability of the iPhone SDK. I downloaded it and someday plan to play around with it, though with the SDK already having gone through 4 or 5 beta releases (each a ~2GB download) I’ll probably wait a long time before cracking it open. However, for web applications the best [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/iphone1.png" align="right" />With much fanfare Apple announced the availability of the <a href="http://developer.apple.com/iphone/">iPhone SDK</a>. I downloaded it and someday plan to play around with it, though with the SDK already having gone through 4 or 5 beta releases (each a ~2GB download) I’ll probably wait a long time before cracking it open. However, for web applications <em>the best way to integrate with an iPhone is still through the browser</em>.</p>
<p>Unfortunately Apple didn&#8217;t provide much help in the form of html or css to make your website &#8220;iPhone-y&#8221;. They <a href="http://developer.apple.com/webapps/">provide</a> documentation on elements like iPhone specific events (&#8220;onorientationchange&#8221;) and details about how Safari works on the iPhone in terms of zooming, etc., but nothing that offers guidance on how to make an application look like it belongs on the iPhone.</p>
<p>Enter <a href="http://joehewitt.com/">Joe Hewitt</a> and <a href="http://code.google.com/p/iui/">iUI</a>. iUI takes HTML that follows a simple set of conventions and does all the heavy lifting to enable you to easily build a version of your site that is tailored for the iPhone experience. I <a href="http://www.aaronlerch.com/blog/2007/10/27/writing-web-apps-for-the-iphone/">first started using iUI</a> before ASP.NET MVC was publicly introduced, and I specifically remember thinking how much iUI was built for &#8220;<a href="http://www.hanselman.com/blog/ASPNETMVCWebFormsUnplugged.aspx">webforms unplugged</a>&#8220;. Let&#8217;s take a quick look at an example of how iUI works, and how to use it with ASP.NET MVC.</p>
<p>If you’re the type that likes to get their hands dirty first, <a href="http://s3.amazonaws.com:80/aaronlerch.com/files/iUISample.v1.zip">download the code here</a>.</p>
<h1>CSS Zen Garden</h1>
<p>iUI is literally nothing more than some javascript, some css, and a bunch of image assets. It’s how things are supposed to work with HTML and it’s beautiful, like the <a href="http://www.csszengarden.com/">CSS Zen Garden</a>. It also has some simple conventions that I’ll summarize like so: “write HTML the way it was intended”. &lt;ul&gt; or &lt;ol&gt; for lists, and &lt;div&gt; or &lt;form&gt; for dialogs and pages. Easy enough, right? There’s not a ton to iUI but for this post I’ll start simple. Let’s create a list of products that we want to display like so:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/iui-product_list_screenshot.png" /></p>
<p>This is the HTML behind the list itself (not including the top toolbar, though the “title” attribute of the list controls the text shown in the center of the toolbar):</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">ul</span> <span class="attr">id</span><span class="kwrd">="products"</span> <span class="attr">title</span><span class="kwrd">="Products"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/1"</span><span class="kwrd">&gt;</span>Alice Mutton<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/2"</span><span class="kwrd">&gt;</span>Aniseed Syrup<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/3"</span><span class="kwrd">&gt;</span>Boston Crab Meat<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/4"</span><span class="kwrd">&gt;</span>Camembert Pierrot<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/5"</span><span class="kwrd">&gt;</span>Carnarvon Tigers<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/6"</span><span class="kwrd">&gt;</span>Chai<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/7"</span><span class="kwrd">&gt;</span>Chang<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/8"</span><span class="kwrd">&gt;</span>Chartreuse verte<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">ul</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.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; }</style>
<p>iUI does the heavy lifting to format the list in the iPhone style, and will dynamically load any linked content using an AJAX call and render it in-place, replacing the current list (“products”). iUI handles sliding in the new content from the right-hand side, just like a native iPhone application.</p>
<p>You could also reference another list defined within the same page, for example if you had a very short list of items and had each list item’s “linked content” also included in the page, like this:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">ul</span> <span class="attr">id</span><span class="kwrd">="products"</span> <span class="attr">title</span><span class="kwrd">="Products"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="#subproduct1"</span><span class="kwrd">&gt;</span>Product 1<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">ul</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;</span><span class="html">ul</span> <span class="attr">id</span><span class="kwrd">="subproduct1"</span> <span class="attr">title</span><span class="kwrd">="Related Products"</span><span class="kwrd">&gt;</span>
   <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;</span>Sub Item 1<span class="kwrd">&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
   <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;</span>Sub Item 2<span class="kwrd">&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">ul</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.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; }</style>
<h1>The Root Page</h1>
<p>iUI will dynamically render partial content into the current view, but it needs an initial root page describing the main layout. The easiest way to figure out what is needed is to look at one of the examples that iUI includes, but in a nutshell you’ll probably need at least two elements: the toolbar (the heading) and some content. To support the example above of a product list, our entire root page could look like this:</p>
<pre class="csharpcode"><span class="kwrd">&lt;!</span><span class="html">DOCTYPE</span> <span class="attr">html</span> <span class="attr">PUBLIC</span> <span class="kwrd">"-//W3C//DTD XHTML 1.0 Strict//EN"</span> <span class="kwrd">"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">html</span> <span class="attr">xmlns</span><span class="kwrd">="http://www.w3.org/1999/xhtml"</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">head</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">meta</span> <span class="attr">http-equiv</span><span class="kwrd">="Content-Type"</span> <span class="attr">content</span><span class="kwrd">="text/html; charset=iso-8859-1"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">title</span><span class="kwrd">&gt;</span>Northwind Explorer<span class="kwrd">&lt;/</span><span class="html">title</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">meta</span> <span class="attr">name</span><span class="kwrd">="viewport"</span> <span class="attr">content</span><span class="kwrd">="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">style</span> <span class="attr">type</span><span class="kwrd">="text/css"</span> <span class="attr">media</span><span class="kwrd">="screen"</span><span class="kwrd">&gt;</span>@import "../../Content/iui/iui.css";<span class="kwrd">&lt;/</span><span class="html">style</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">type</span><span class="kwrd">="application/x-javascript"</span> <span class="attr">src</span><span class="kwrd">="../../Content/iui/iui.js"</span><span class="kwrd">&gt;&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">head</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">body</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">div</span> <span class="attr">class</span><span class="kwrd">="toolbar"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">h1</span> <span class="attr">id</span><span class="kwrd">="pageTitle"</span><span class="kwrd">&gt;&lt;/</span><span class="html">h1</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">a</span> <span class="attr">id</span><span class="kwrd">="backButton"</span> <span class="attr">class</span><span class="kwrd">="button"</span> <span class="attr">href</span><span class="kwrd">="#"</span><span class="kwrd">&gt;&lt;/</span><span class="html">a</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ul</span> <span class="attr">id</span><span class="kwrd">="products"</span> <span class="attr">title</span><span class="kwrd">="Products"</span> <span class="attr">selected</span><span class="kwrd">="true"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/1"</span><span class="kwrd">&gt;</span>Alice Mutton<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/2"</span><span class="kwrd">&gt;</span>Aniseed Syrup<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/3"</span><span class="kwrd">&gt;</span>Boston Crab Meat<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/4"</span><span class="kwrd">&gt;</span>Camembert Pierrot<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/5"</span><span class="kwrd">&gt;</span>Carnarvon Tigers<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/6"</span><span class="kwrd">&gt;</span>Chai<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/7"</span><span class="kwrd">&gt;</span>Chang<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">li</span><span class="kwrd">&gt;&lt;</span><span class="html">a</span> <span class="attr">href</span><span class="kwrd">="/products/index/8"</span><span class="kwrd">&gt;</span>Chartreuse verte<span class="kwrd">&lt;/</span><span class="html">a</span><span class="kwrd">&gt;&lt;/</span><span class="html">li</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">ul</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">body</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">html</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.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; }</style>
<p>The site will initially show the list of products, and when the user clicks on a product, the &lt;ul id=”products” title=”Products” selected=”true”&gt;…&lt;/ul&gt; element will be wholesale replaced with the content loaded by an AJAX call to “/products/index/[number]”.</p>
<h1>Hooking up iUI to MVC</h1>
<p>First things first &#8211; <a href="http://code.google.com/p/iui/source/browse/trunk/iui">download</a> the latest iUI assets from the google code repository trunk. You&#8217;ll get the latest bug fixes and features, which I&#8217;ve found to be helpful. As a side note, you can view some samples directly from the repository itself &#8211; like the <a href="http://iui.googlecode.com/svn/trunk/samples/music.html">music example</a>. Put the downloaded files in the Content directory:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/iui-assets.png" /></p>
<p>Define your main page—the main entry point to the site. I chose /home/index in my example. This is where you’ll reference the iUI javascript and css assets, and define the initial structure of your page.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/iui-products_home.png" /></p>
<p>One big catch that I already mentioned with iUI is that it expects links (whether AJAX-loaded or in-page references) to return HTML fragments. It literally takes the results of an AJAX call to a given URL and sets the innerHTML of the content to replace.</p>
<p>This means that every other page in our application should return partial content. For example, when I click on “Products” this is the only content of the view page that lists the products:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/iui-product_list.png" /></p>
<p>As you can see, it’s simply building the list itself and rendering the partial HTML content as a response.</p>
<p>You can connect with an iPhone on your local network with a wifi connection, but it’s much easier to install and test with <a href="http://www.apple.com/safari/">Safari for Windows</a>. Both Safari for Windows and the iPhone’s mobile Safari use the <a href="http://webkit.org/">WebKit</a> engine so the rendering experience is about as close as you can get. Shrink the browser to approximately the size of the iPhone screen and you’d never know you didn’t spend the $400+ on an iPhone. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/iui-safari.png" /></p>
<p>You can <a href="http://s3.amazonaws.com:80/aaronlerch.com/files/iUISample.v1.zip">download the first version of my example project here</a>.</p>
<h1>Up Next</h1>
<p>In future posts I’ll explore some more of iUI’s features such as adding a product page to view details of a product in a friendly way (I’ve included this in the example project already), rendering partial lists (allowing the user to expand the list incrementally), detecting the user agent and loading iPhone views vs. “normal” views, and more. I’ll update the example project as we go!</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://www.aaronlerch.com/blog/2008/06/08/rock-the-iphone-with-aspnet-mvc/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.aaronlerch.com/blog/2008/06/08/rock-the-iphone-with-aspnet-mvc/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/06/08/rock-the-iphone-with-aspnet-mvc/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>First thoughts on ASP.NET MVC Preview 3</title>
		<link>http://www.aaronlerch.com/blog/2008/05/27/first-thoughts-on-aspnet-mvc-preview-3/</link>
		<comments>http://www.aaronlerch.com/blog/2008/05/27/first-thoughts-on-aspnet-mvc-preview-3/#comments</comments>
		<pubDate>Wed, 28 May 2008 02:57:11 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[asp.net mvc]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/05/27/first-thoughts-on-aspnet-mvc-preview-3/</guid>
		<description><![CDATA[I had a chance to play with the latest ASP.NET MVC drop tonight. There&#8217;s a few changes (some of which came in Preview 2) but a few items caught my eye fairly quickly.
ActionResult
This change came with Preview 2, but it&#8217;s worth mentioning. Instead of controller actions returning void, they now return an ActionResult instance. This [...]]]></description>
			<content:encoded><![CDATA[<p>I had a chance to play with the latest <a href="http://www.asp.net/mvc/">ASP.NET MVC</a> drop tonight. There&#8217;s a few changes (<a href="http://flux88.com/ASPNETMVCPreview2Update.aspx">some of which came in Preview 2</a>) but a few items caught my eye fairly quickly.</p>
<p><strong>ActionResult</strong></p>
<p>This change came with Preview 2, but it&#8217;s worth mentioning. Instead of controller actions returning void, they now return an ActionResult instance. This increases testability and separates functionality. Testability because now controllers can be tested without mocking out all the requirements for invoking the view, and functionality because the loading and invoking of an action&#8217;s view is encapsulated in a class structure apart from the controllers.</p>
<p><strong>JsonResult</strong></p>
<p>Something that is included new in Preview 3 is JsonResult (a subclass of ActionResult). It looks like some of <a href="http://www.aaronlerch.com/blog/2008/01/01/unifying-web-sites-and-web-services-with-the-aspnet-mvc-framework/">my crazy ideas</a> weren&#8217;t so crazy after all? A new method on the controller, &quot;Json()&quot;, takes a serializable object and returns a JsonResult which uses the obsoleted (whoops??) JavaScriptSerializer to render the object as JSON.</p>
<p>So a controller&#8217;s action could look like this:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/controller-json-1.png" /></p>
<p><strong>RedirectToRoute</strong></p>
<p>If a controller action needed to redirect, our only option (until now) has been RedirectToAction which accepts an action name and optional controller name. That&#8217;s not bad, but now we have RedirectToRoute which allows us to redirect to a named route, making things more flexible and easier to change (without mass <a href="http://www.aaronlerch.com/blog/2007/03/28/visual-studio-find-and-replace-regular-expressions/">find/replacing</a> all over the place).</p>
<p><strong>And more&#8230;</strong></p>
<p>Scott Guthrie has <a href="http://weblogs.asp.net/scottgu/archive/2008/05/27/asp-net-mvc-preview-3-release.aspx">more details</a>, and Scott Hanselman (so many Scotts!) has a few <a href="http://www.hanselman.com/blog/ASPNETMVCPreview3.aspx">updated screencasts</a>. Be sure to check them out.</p>
<p>Things with MVC are solidifying and starting to look pretty good. Check out the <a href="http://mvccontrib.org/">MvcContrib</a> or <a href="http://code.google.com/p/codecampserver/">CodeCampServer</a> projects for some decent reference implementations.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/05/27/first-thoughts-on-aspnet-mvc-preview-3/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Testing TempData, and Mocking SessionState</title>
		<link>http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/</link>
		<comments>http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 00:07:10 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[asp.net mvc]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/</guid>
		<description><![CDATA[About a month and a half ago Ben Scheirman wrote about testing TempData in ASP.NET MVC. It&#8217;s good stuff, and aside from changes between Preview 1 and Preview 2, it still works fine. (See Scott Hanselman&#8217;s post for some Preview 2-friendly mock helpers using Rhino Mocks.)
While I can easily understand what Ben&#8217;s code is doing, [...]]]></description>
			<content:encoded><![CDATA[<p>About a month and a half ago <a href="http://flux88.com/">Ben Scheirman</a> wrote about <a href="http://flux88.com/testingtempdatainaspnetmvc.aspx">testing TempData in ASP.NET MVC</a>. It&#8217;s good stuff, and aside from changes between Preview 1 and Preview 2, it still works fine. (See <a href="http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx">Scott Hanselman&#8217;s post</a> for some Preview 2-friendly mock helpers using Rhino Mocks.)</p>
<p>While I can easily understand what Ben&#8217;s code is doing, what I couldn&#8217;t figure out is <em>why</em> it worked. If you reflect over TempDataDictionary (the type of the Controller.TempData property), you&#8217;ll see that the data type it persists to the session is an internal structure.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/tempdata-reflector.png" /></p>
<p>Ben&#8217;s code, however, mocks out the Session to return the expected TempDataDictionary object. By all counts, that should fail, since the TempDataDictionary won&#8217;t be getting back the values it expects&#8211;it expects the internal map structure.</p>
<p>Well, it turns out I was glossing over one very important fact. TempDataDictionary was written to be smart enough that if the underlying session store either didn&#8217;t work, or didn&#8217;t provide the right data, TempData will continue to operate as normal&#8211;<em>for the current request only</em>. You can see below that if the session data was null or wasn&#8217;t the right type, it just creates a new internal map.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/tempdata-reflector2.png" /><br />
<font size="1">(image cut off for space)</font></p>
<p>One of the benefits of TempData is the cross-request persistence via the session. You might not have known it, but when you call RedirectToAction in your controller action, for example, it&#8217;s actually resulting in a 300-level HTTP redirect, which means an entirely new HttpContext for the next request. It&#8217;s basically deferring to the browser to perform the redirect.</p>
<p>So, while Ben&#8217;s code will definitely work, here&#8217;s an extension method that can help with mocking out the session a little more &#8220;correctly&#8221;:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> NullifySessionState(<span class="kwrd">this</span> HttpSessionStateBase session)
{
    SetupResult.For(session[<span class="kwrd">null</span>]).IgnoreArguments().Return(<span class="kwrd">null</span>);
    session[<span class="kwrd">null</span>] = <span class="kwrd">null</span>;
    LastCall.IgnoreArguments();
}</pre>
<style type="text/css">.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; }</style>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/03/12/testing-tempdata-and-mocking-sessionstate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Displaying [foo] on every page of an ASP.NET MVC application</title>
		<link>http://www.aaronlerch.com/blog/2008/01/26/displaying-foo-on-every-page-of-an-aspnet-mvc-application/</link>
		<comments>http://www.aaronlerch.com/blog/2008/01/26/displaying-foo-on-every-page-of-an-aspnet-mvc-application/#comments</comments>
		<pubDate>Sat, 26 Jan 2008 15:15:16 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[asp.net mvc]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/01/26/displaying-foo-on-every-page-of-an-aspnet-mvc-application/</guid>
		<description><![CDATA[ Frequently in web applications there&#8217;s a requirement like this: &#8220;Every page should display [foo].&#8221; Where &#8220;foo&#8221; can be literally anything: a list of favorites, sponsors, news, or whatever &#8211; it&#8217;s data. In what I&#8217;ll call &#8220;normal, by a long shot&#8221; ASP.NET cases, universally displayed data will probably be encapsulated in a user control and [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://aaronlerch.com.s3.amazonaws.com/images/aspnetmvcfooscreen.png" align="right" /> Frequently in web applications there&#8217;s a requirement like this: &#8220;Every page should display [foo].&#8221; Where &#8220;foo&#8221; can be literally anything: a list of favorites, sponsors, news, or whatever &#8211; <em>it&#8217;s data</em>. In what I&#8217;ll call &#8220;normal, by a long shot&#8221; ASP.NET cases, universally displayed data will probably be encapsulated in a user control and put on a master page. The master page includes the user control on all pages, and the user control loads the data and renders it, and it was all declared Good.</p>
<p>The MVC world (<a href="http://www.hanselman.com/blog/ASPNETMVCWebFormsUnplugged.aspx">ASP.NET &#8220;unplugged&#8221;</a>) turns everything on it&#8217;s head. Maintaining a clean separation of concerns means the controller is responsible for ensuring the appropriate data is made available to the appropriate view. The view does not load data on it&#8217;s own, nor does it know or care where the data came from. And the view was declared Dumb.</p>
<p>Views aren&#8217;t really dumb, of course, they have to render data, and the MVC framework does give them some tools to help. For example, the ViewMasterPage base class exposes helpers for constructing links, accessing the view data, etc.</p>
<p><img src="http://aaronlerch.com.s3.amazonaws.com/images/viewmasterpage.png" /></p>
<p>So what do you do in the ASP.NET MVC world when you&#8217;ve got a &#8220;user control&#8221; embedded in your master page that needs specific data? Let&#8217;s say that hypothetically speaking you&#8217;re working on a <a href="http://code.google.com/p/codecampserver/">CodeCampServer</a> project, and you need to, oh I don&#8217;t know, display a list of code camp Sponsors (ahem, &#8220;Contributors&#8221;) on every single page?</p>
<p>The way I see it, you&#8217;ve got three options:</p>
<p><strong>1. &#8220;Global&#8221; data for global display</strong></p>
<p>Data can be loaded at a low level for each and every request. Something like:</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">void</span> Application_BeginRequest(<span class="kwrd">object</span> sender, EventArgs e)
{
    <span class="kwrd">this</span>.Context.Items[<span class="str">"FooData"</span>] = <span class="kwrd">new</span> FooData();
}</pre>
<style type="text/css">.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; }</style>
<p>The pro is that FooData will be available to every view (though not through the standard ViewData). Unfortunately if this data is expensive to compute (or even if it isn&#8217;t) it&#8217;ll be loaded for <em>every request</em>, no matter what. Oh, and no one in their right mind would actually do it this way. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  There&#8217;s that, too.</p>
<p><strong>2. Controller.OnPreAction</strong></p>
<p>The main Controller class exposes a virtual OnPreAction method which offers a hook just before an action is invoked. For global data, all controllers in your application could derive from a common base controller class which loads the necessary data.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">bool</span> OnPreAction(<span class="kwrd">string</span> actionName, System.Reflection.MethodInfo methodInfo)
{
    ViewData[<span class="str">"FooData"</span>] = <span class="kwrd">new</span> FooData();
    <span class="kwrd">return</span> <span class="kwrd">base</span>.OnPreAction(actionName, methodInfo);
}</pre>
<style type="text/css">.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; }</style>
<p>Views will be able to access the data via the ViewData property, as normal. With single inheritance in C#, a required base class just for common data can potentially cause problems.</p>
<p><strong>3. Call &#8220;RenderAction&#8221; from the view</strong></p>
<p><a href="http://www.marklio.com/marklio/PermaLink,guid,90f5b539-3f7f-4309-a70a-fe98fdbc7347.aspx">RenderAction</a> is an extension method that allows a view to reference a Controller and Action and have the results be rendered in-place within the view.</p>
<p><img src="http://aaronlerch.com.s3.amazonaws.com/images/aspnetmvcrenderaction.png" /></p>
<p>The &#8220;Tags&#8221; controller and &#8220;Cloud&#8221; action would render a view that generated an HTML fragment that would fit within the current view. This approach has advantages of only loading data when absolutely necessary and changing your view doesn&#8217;t necessarily require changing the application code to match.</p>
<p>There could be questions about separation of concerns: a view is determining what data to include regardless of what it&#8217;s controller gave it. But the same is true for the other solutions as well &#8211; this is just more dynamic.</p>
<p>Another advantage to this approach is that if <a href="http://www.aaronlerch.com/blog/2008/01/01/unifying-web-sites-and-web-services-with-the-aspnet-mvc-framework/">you set it up right</a>, with no extra work your &#8220;viewlets&#8221; (the views that render fragments) can return JSON serialized data for an AJAX call, for example.</p>
<p>I&#8217;m pro-RenderAction, but in discussions I&#8217;ve had with people it hasn&#8217;t been as big a hit with them. What are your thoughts? Am I missing some pros or cons? Are there more options that I didn&#8217;t include? Is it really just an app-by-app decision, or is there an emerging convention that should be followed?</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://www.aaronlerch.com/blog/2008/01/26/displaying-foo-on-every-page-of-an-aspnet-mvc-application/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.aaronlerch.com/blog/2008/01/26/displaying-foo-on-every-page-of-an-aspnet-mvc-application/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/01/26/displaying-foo-on-every-page-of-an-aspnet-mvc-application/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
