<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Jon Galloway</title><link>http://weblogs.asp.net/jgalloway/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/jongalloway" /><feedburner:info uri="jongalloway" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Technology/Tech News</media:category><itunes:explicit>no</itunes:explicit><itunes:subtitle></itunes:subtitle><itunes:category text="Technology"><itunes:category text="Tech News" /></itunes:category><geo:lat>32.761801</geo:lat><geo:long>-117.012737</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-nc/2.0/</creativeCommons:license><image><url>http://farm1.static.flickr.com/175/buddyicons/36836555@N00.jpg?1169797019</url><title>Jon Galloway</title></image><feedburner:emailServiceId>jongalloway</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><title>ASUS Zenbook UX31 - First Look</title><link>http://feedproxy.google.com/~r/jongalloway/~3/B5wl9Oce798/asus-zenbook-ux31-first-look.aspx</link><pubDate>Sat, 28 Jan 2012 08:53:01 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8270496</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8270496</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2012/01/28/asus-zenbook-ux31-first-look.aspx#comments</comments><description>&lt;p&gt;I've been through several laptops over the years, three in the past two years. I had an old Dell beater as a fallback, but for a while my main laptop was a Dell Latitude XT2. The XT2 seemed promising - a small laptop with a touch screen - but poor drivers and slow performance made it barely usable. It was bad enough trying to do day to day work on it, but when I used it to give technical presentations it was flat out embarrassing. That's why, when I was up for a new work laptop, I jumped at the &lt;a href="http://www.amazon.com/gp/product/B004U5Y9LC?ie=UTF8&amp;amp;tag=jongall-20&amp;amp;linkCode=shr&amp;amp;camp=213733&amp;amp;creative=393185&amp;amp;creativeASIN=B004U5Y9LC&amp;amp;ref_=sr_1_2&amp;amp;s=electronics&amp;amp;qid=1327740526&amp;amp;sr=1-2"&gt;Lenovo W520&lt;/a&gt;. The W520 is an enormous brute of a machine in every sense - literally more powerful than most desktop machines, and not much smaller. That's fine, I thought - I'll happily trade convenience for a machine that actually works.&lt;/p&gt;  &lt;p&gt;I tell you that history to explain why, &lt;strong&gt;when I was offered the opportunity to review an Intel Ultrabook, I was pretty skeptical&lt;/strong&gt;. I reviewed some of the different options available and - while they looked good - I didn't expect a lot in the way of power, especially when I saw that the prices were pretty reasonable.&lt;/p&gt;  &lt;p&gt;As I said, I was offered an Ultrabook in exchange for a review, so here's the disclaimer: &lt;em&gt;I received an ASUS Zenbook 31 for free in the hope that I would mention it on my blog. Regardless, I only recommend things I personally endorse and would recommend. I'm disclosing this in accordance with the FTC's &lt;/em&gt;&lt;a href="http://www.ftc.gov/os/2009/10/091005revisedendorsementguides.pdf"&gt;&lt;em&gt;Guides Concerning the Use of Endorsements and Testimonials in Advertising&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. Just in case, I also cleared it with my employer's legal / corporate affairs team. I also made sure the agreement said that my review would be my honest opinion, and that's what this is. This is my opinion alone, and doesn't necessarily reflect the views of my employer.&amp;lt;/disclaimer&amp;gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The offer was to review an Ultrabook from Intel's current lineup, so step one for me was to compare the options. There are a lot of good choices out there, and while I was interested in the &lt;a href="http://www.theverge.com/2011/11/8/2546923/lenovo-ideapad-u300s-ultrabook-review"&gt;Lenovo U300s (a pretty gorgeous machine)&lt;/a&gt; I kept coming back to the &lt;a href="http://www.amazon.com/gp/product/B005SY32Q2?ie=UTF8&amp;amp;tag=jongall-20&amp;amp;linkCode=shr&amp;amp;camp=213733&amp;amp;creative=393177&amp;amp;creativeASIN=B005SY32Q2&amp;amp;ref_=sr_1_1&amp;amp;s=electronics&amp;amp;qid=1327740305&amp;amp;sr=1-1"&gt;ASUS Zenbook&lt;/a&gt;. It stood out for a number of reasons, but one big one was the screen resolution. Just about every comparable laptop out there maxes out at a screen resolution of 1366x768 or 1440x900 (including the &lt;a href="http://www.engadget.com/2011/10/21/asus-zenbook-ux31-review/"&gt;top MacBook Airs&lt;/a&gt;), &lt;strong&gt;the Zenbook UX31 goes all the way up to 1600x900&lt;/strong&gt;. Based on recent history with trying to work and give technical presentations using small laptops, I wasn't interested in reviewing anything I couldn't do real work and consider presenting with. If you're looking for an ultrabook form factor laptop to &lt;strong&gt;do real work&lt;/strong&gt; on (as opposed to web and media) I think those extra pixels are a big deal.&lt;/p&gt;  &lt;h2&gt;Unboxing&lt;/h2&gt;  &lt;p&gt;This laptop was very well packaged. It was obvious from the start that attention had been paid to quality and elegance, and I think it works. This felt like unpacking a quality consumer product, not your typical laptop box full of random papers and promotional CD-ROMS.&lt;/p&gt;  &lt;p&gt;&lt;a title="IMG_6172" href="http://www.flickr.com/photos/36836555@N00/6773798709/"&gt;&lt;img border="0" alt="IMG_6172" src="http://farm8.static.flickr.com/7147/6773798709_0e62c6b41e_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After removing the small but solid Zenbook, I found a sturdy looking carrying case. As others have noted, a carrying case for this seemingly indestructible laptop seems like overkill, but it sure looks nice.&lt;/p&gt;  &lt;p&gt;&lt;a title="IMG_6173" href="http://www.flickr.com/photos/36836555@N00/6773806567/"&gt;&lt;img border="0" alt="IMG_6173" src="http://farm8.static.flickr.com/7149/6773806567_4f12d31242_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After removing the Zenbook and the case (pictured later), you find a nice introductory card on top of a small box with other necessary but not beautiful stuff (owner's manual, warranty card, etc.). Again, opening this laptop feels like an experience.&lt;/p&gt;  &lt;p&gt;&lt;a title="IMG_6174" href="http://www.flickr.com/photos/36836555@N00/6773822177/"&gt;&lt;img border="0" alt="IMG_6174" src="http://farm8.static.flickr.com/7012/6773822177_1143bf3caa_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So at the risk of being incredibly nitpicky here, I found it odd that the Zenbook card was completely devoted to talking about features of the Zenbook, and none said anything like &amp;quot;You'll need to plug in your Zenbook before using it.&amp;quot; Yes, I'm a computer guy who knows (expects) that laptop batteries won't stay charged during shipping and the dang thing needs to be plugged in when you open the package, but I'm thinking like a non-techy consumer who's buying a consumer electronic gizmo here. When I take the Zenbook out of the box and try to turn it on, nothing happens. The welcome card should cover that.&lt;/p&gt;  &lt;p&gt;On to the actual laptop - the Zenbook!&lt;/p&gt;  &lt;p&gt;&lt;a title="IMG_6177" href="http://www.flickr.com/photos/36836555@N00/6773868143/"&gt;&lt;img border="0" alt="IMG_6177" src="http://farm8.static.flickr.com/7013/6773868143_f69baf0eee_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is a good looking, solid machine. It's small but heavy. When I showed it to my 7yo daughter and asked what she thought it looked like, she said, &amp;quot;Expensive!&amp;quot; I agree, and while this doesn't come through in a blog post, the laptop itself feels very substantial. It's not heavy, but it feels hefty for its petite size.&lt;/p&gt;  &lt;p&gt;The case is solidly constructed and looks nice.&lt;/p&gt;  &lt;p&gt;&lt;a title="IMG_6220" href="http://www.flickr.com/photos/36836555@N00/6773888317/"&gt;&lt;img border="0" alt="IMG_6220" src="http://farm8.static.flickr.com/7035/6773888317_7937589213_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;A Few (Minor) Complaints about the First Run Experience&lt;/h2&gt;  &lt;p&gt;For such a beautiful unboxing experience, I had (unrealistic?) expectations for the first run experience. Things went downhill a little bit when I turned the Zenbook on. The first prompt I got required me to accept an agreement to install the Bing Bar.&lt;/p&gt;  &lt;p&gt;&lt;a title="IMG_6183" href="http://www.flickr.com/photos/36836555@N00/6773872363/"&gt;&lt;img border="0" alt="IMG_6183" src="http://farm8.static.flickr.com/7014/6773872363_93b3daed67_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What was especially frustrating with this prompt was that there was no choice - in order to start the machine up, I needed to agree to the Bing Bar license - the Next button is disabled until I do. That really broke the &amp;quot;fancy&amp;quot; feeling. Things continued in that direction after the installation completed, with a bunch of annoying dialogs:&lt;/p&gt;  &lt;p&gt;&lt;a title="Desktop -2" href="http://www.flickr.com/photos/36836555@N00/6773874871/"&gt;&lt;img border="0" alt="Desktop -2" src="http://farm8.static.flickr.com/7033/6773874871_c72c7f12e8_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Look, I get that crapware manufacturers pay computer manufacturers money to bundle trial software, and that (kind of) benefits consumers by lowering prices. That's the real world. I think this could be done better, though. Either charge a bit more and ship a beautiful first run experience, or at least bundle all the lame crapware dialogs into one. The overlapping, uncoordinated dialogs feel cheap cheap cheap, which ruins an up-til-then beautiful experience. It's something I expect in a budget laptop, but not something as beautiful (and as beautifully packaged) as the Zenbook.&lt;/p&gt;  &lt;p&gt;Curious, I took a quick look at the pre-installed goodies, and wasn't surprised to see quite a list:&lt;/p&gt;  &lt;p&gt;&lt;a title="2012-01-25 01h13_20" href="http://www.flickr.com/photos/36836555@N00/6773876061/"&gt;&lt;img border="0" alt="2012-01-25 01h13_20" src="http://farm8.static.flickr.com/7154/6773876061_2d8fb9d6b4_b.jpg" width="717" height="446" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So, I could (and will) uninstall the junkware, but was a little disappointed to see it as a part of an otherwise beautiful setup install experience. I don't want to give the wrong impression here - these are minor annoyances, and don't really significantly detract from the actual use of this beautiful machine after the first few minutes. It's just that they've obviously invested a lot of effort in packaging, and it's a shame to see that emotional appeal damaged even in the slightest when I turn the machine on.&lt;/p&gt;  &lt;h2&gt;Fast&lt;/h2&gt;  &lt;p&gt;Regardless of any unwanted pre-installed goodies, this thing is snappy right out of the box. Without installing any updates or uninstalling anything, I got a 5.6 WEI.&lt;/p&gt;  &lt;p&gt;&lt;a title="2012-01-25 10h09_42" href="http://www.flickr.com/photos/36836555@N00/6773881651/"&gt;&lt;img border="0" alt="2012-01-25 10h09_42" src="http://farm8.static.flickr.com/7143/6773881651_1749f82403_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;These are pretty fast scores. And, more important, so far this thing feels fast. I've been using it for a week and this thing just feels fast all the time.&lt;/p&gt;  &lt;h2&gt;Face Login&lt;/h2&gt;  &lt;p&gt;Okay, I'll talk more about this machine once I've used it for a few weeks, but I wanted to show off one cool feature - Face Login. The webcam locks in on you face and automatically logs you in, as shown below.&lt;/p&gt; &lt;object type="application/x-shockwave-flash" width="400" height="225" data="http://www.flickr.com/apps/video/stewart.swf?v=109786" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"&gt; &lt;param name="flashvars" value="intl_lang=en-us&amp;amp;photo_secret=3bcf629fcc&amp;amp;photo_id=6773555961&amp;amp;hd_default=false"&gt;&lt;/param&gt; &lt;param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=109786"&gt;&lt;/param&gt; &lt;param name="bgcolor" value="#000000"&gt;&lt;/param&gt; &lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=109786" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&amp;photo_secret=3bcf629fcc&amp;photo_id=6773555961&amp;hd_default=false" height="225" width="400"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;p&gt;I've used a few webcam login systems, but none of them have worked near this well. The Face Login system really works - it's fast and it's fun.&lt;/p&gt;  &lt;h2&gt;Summary&lt;/h2&gt;  &lt;p&gt;So far I'm &lt;strong&gt;very impressed&lt;/strong&gt;. While this post focuses on the first few hours with the laptop, the reality is that what's really important is all the hours that follow. I'll write I more detail once I've used this more, but this past week has shown me &lt;strong&gt;that this is an amazing laptop&lt;/strong&gt;. If I was shopping for a new laptop today and my friend showed me this machine&lt;strong&gt;, I'd buy it... and I'm a hard sell&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Some more links for the Zenbook UX31:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;h4&gt;Dave Ward's &lt;a href="http://encosia.com/the-asus-zenbook-ux31-initial-impressions/"&gt;The ASUS Zenbook UX31: Initial impressions&lt;/a&gt;&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;The Verge's &lt;a href="http://www.engadget.com/2011/10/21/asus-zenbook-ux31-review/"&gt;ASUS Zenbook UX31 review&lt;/a&gt;&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;The &lt;a href="http://www.amazon.com/gp/product/B005SY32Q2?ie=UTF8&amp;amp;tag=jongall-20&amp;amp;linkCode=shr&amp;amp;camp=213733&amp;amp;creative=393177&amp;amp;creativeASIN=B005SY32Q2&amp;amp;ref_=sr_1_1&amp;amp;s=electronics&amp;amp;qid=1327740305&amp;amp;sr=1-1"&gt;Zenbook UX31 on Amazon&lt;/a&gt;&lt;/h4&gt;   &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8270496" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=B5wl9Oce798:kEMKHmvBhZQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=B5wl9Oce798:kEMKHmvBhZQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=B5wl9Oce798:kEMKHmvBhZQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=B5wl9Oce798:kEMKHmvBhZQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=B5wl9Oce798:kEMKHmvBhZQ:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=B5wl9Oce798:kEMKHmvBhZQ:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=B5wl9Oce798:kEMKHmvBhZQ:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/B5wl9Oce798" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/Review/default.aspx">Review</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2012/01/28/asus-zenbook-ux31-first-look.aspx</feedburner:origLink></item><item><title>10 Things ASP.NET Developers Should Know About Web.config Inheritance and Overrides</title><link>http://feedproxy.google.com/~r/jongalloway/~3/JHXpr59NjP8/10-things-asp-net-developers-should-know-about-web-config-inheritance-and-overrides.aspx</link><pubDate>Wed, 18 Jan 2012 00:09:24 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8261171</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>24</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8261171</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2012/01/17/10-things-asp-net-developers-should-know-about-web-config-inheritance-and-overrides.aspx#comments</comments><description>&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/ms178683.aspx"&gt;ASP.NET configuration system&lt;/a&gt; is build around the idea of inheritance:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Each Web.config file applies configuration settings to the directory that it is in and to all of the child directories below it&lt;/strong&gt;. Settings in &lt;strong&gt;child directories can optionally override or modify settings that are specified in parent directories&lt;/strong&gt;. Configuration settings in a Web.config file can optionally be applied to individual files or subdirectories by specifying a path in a &lt;a href="http://msdn.microsoft.com/en-us/library/b6x6shw7.aspx"&gt;location&lt;/a&gt; element.&lt;/p&gt;    &lt;p&gt;The root of the ASP.NET configuration hierarchy is the systemroot\Microsoft.NET\Framework\versionNumber\CONFIG\Web.config file, which includes settings that apply to all ASP.NET applications that run a specific version of the .NET Framework. Because each ASP.NET application inherits default configuration settings from the root Web.config file, you need to create Web.config files only for settings that override the default settings.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;For a lot of sites, you don't really need to know about that - you can get by with one Web.config file for the site. But, knowing how the inheritance works - and how to control it - can really help out.&lt;/p&gt;  &lt;p&gt;I've noticed that a lot of the questions I answer questions on forums, StackOverflow, and internal e-mail lists can be solved by better understanding how ASP.NET configuration inheritance and overrides work. And so, a bunch of tips about how ASP.NET configuration inheritance and overrides work! I'll start with some basics, but there are some towards the end I'll bet most ASP.NET developers don't know.&lt;/p&gt;  &lt;h2&gt;Tip 1: Using Web.config files in site subfolders&lt;/h2&gt;  &lt;p&gt;And ASP.NET website's Web.config is part of an inheritance chain. Your website's subfolders can have Web.config - an example is the Web.config file in an ASP.NET MVC application's View folder which does things like preventing directly viewing the View templates:&lt;/p&gt;  &lt;p&gt;&lt;a title="2012-01-12 23h57_09" href="http://www.flickr.com/photos/36836555@N00/6688643777/"&gt;&lt;img border="0" alt="2012-01-12 23h57_09" src="http://farm8.static.flickr.com/7035/6688643777_6e670b45d4_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This allows for setting general settings at the site level and overriding them when necessary. Any settings in the base Web.config that aren't overridden in the subfolder stay in effect, so the &amp;quot;child&amp;quot; Web.config can be pretty small. You can continue to nest them, so sub-sub-subfolders can get their own Web.config if needed. Some of the most common uses of subfolders are to restrict permission (e.g. requiring authentication or restricting access to resources), but you can also use them to do things like include default namespaces in Views, toggle handlers, etc.&lt;/p&gt;  &lt;h2&gt;Tip 2: Understand how your site Web.config inherits its settings&lt;/h2&gt;  &lt;p&gt;But there's an inheritance chain above the site, too. Here's a simplified version from the MSDN docs:&lt;/p&gt;  &lt;table border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;th&gt;         &lt;p&gt;Configuration level&lt;/p&gt;       &lt;/th&gt;        &lt;th&gt;         &lt;p&gt;File name&lt;/p&gt;       &lt;/th&gt;        &lt;th&gt;         &lt;p&gt;File description&lt;/p&gt;       &lt;/th&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;Server&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Machine.config&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;The Machine.config file contains the ASP.NET schema for all of the Web applications on the server. This file is at the top of the configuration merge hierarchy.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;IIS&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;ApplicationHost.config&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;ApplicationHost.config is the root file of the IIS 7.0 configuration system. It includes definitions of all sites, applications, virtual directories, and application pools, as well as global defaults for the Web server settings. It is in the following location:&lt;/p&gt;          &lt;p&gt;&lt;span class="code"&gt;%windir%\system32\inetsrv\config&lt;/span&gt; &lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;Root Web&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Web.config&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;The Web.config file for the server is stored in the same directory as the Machine.config file and contains default values for most of the &lt;span&gt;&lt;span class="input"&gt;system.web&lt;/span&gt;&lt;/span&gt; configuration sections. At run time, this file is merged second from the top in the configuration hierarchy.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr style="background-color: #ccd"&gt;       &lt;td&gt;         &lt;p&gt;Web site&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Web.config&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;The Web.config file for a specific Web site contains settings that apply to the Web site and inherit downward through all of the ASP.NET applications and subdirectories of the site.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;ASP.NET application root directory&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Web.config&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;The Web.config file for a specific ASP.NET application is located in the root directory of the application and contains settings that apply to the Web application and inherit downward through all of the subdirectories in its branch.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;ASP.NET application subdirectory&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Web.config&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;The Web.config file for an application subdirectory contains settings that apply to this subdirectory and inherit downward through all of the subdirectories in its branch.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;So your website's configuration's actually inherited a bunch of settings that were set at the server level. That's nice for a few reasons:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It allows the ASP.NET / IIS teams to migrate settings that aren't commonly modified from the project template Web.config files to server defaults, keeping your Web.config files smaller and more readable. For example, &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/08/25/clean-web-config-files-vs-2010-and-net-4-0-series.aspx"&gt;ASP.NET 4 migrated a bunch of handler registrations to Machine.config, so the Empty ASP.NET Application Web.config is slimmed down to about 8 lines&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;You can override things at the server level as needed&lt;/strong&gt;, and they'll take effect for all applications. For example, you can set &lt;a href="http://msdn.microsoft.com/en-us/library/ms228298.aspx"&gt;&amp;lt;deployment retail=&amp;quot;true&amp;quot;&amp;gt;&lt;/a&gt; on production servers to disable trace output and debug capabilities. &lt;/li&gt;    &lt;li&gt;You can &lt;strong&gt;find a lot of useful information in the Machine.config&lt;/strong&gt; default settings since they're stored in plain text. For example, the ASP.NET Membership Provider has some defaults set for password requirements and the membership database, and you can look them up by looking in the appropriate .NET framework version's Machine.config. For a default installation of ASP.NET 4, that's found in C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config with a quick search for &amp;lt;membership&amp;gt;. &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Tip 3: Understand how your Web.config inherits IIS configuration settings&lt;/h2&gt;  &lt;p&gt;This overlaps a bit of Tip 2, but it bears repeating. Long-time ASP.NET developers (myself included) are prone to thinking of ASP.NET and IIS configuration separately, but that all changed with IIS 7. This is all pretty old news, as IIS 7 has been out for a while, but it hasn't been completely absorbed by ASP.NET developers.&lt;/p&gt;  &lt;p&gt;CarlosAg summed this up well in a post from 2006(!) which explained &lt;a href="http://blogs.msdn.com/b/carlosag/archive/2006/04/25/iis7configurationsystem.aspx"&gt;The New Configuration System in IIS 7&lt;/a&gt;.&amp;#160; I'm not going to rehash his post here - go read it. Some important takeaways are that both the ApplicationHost.config and Machine.config feed into the configuration settings in your site's Web.config, as shown in Carlos' diagram:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.carlosag.net/images/hierarchy.png" /&gt;&lt;/p&gt;  &lt;p&gt;In addition to the understanding how things work part of it, this is also good to know because - based on the info in Tip 2 - you can see what the base settings are, and how you can override them in your application's Web.config. This is why you can do pretty advanced things like configure rules on for the &lt;a href="http://learn.iis.net/page.aspx/465/url-rewrite-module-configuration-reference/"&gt;URL Rewrite Module in your application's web.config&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Of course, server administrators don't necessarily want to allow any application on the server to modify settings via Web.config, so there are configurable policies in the ApplicationHost.config which state whether individual applications can override settings. There's also an &lt;a href="http://blogs.iis.net/davcox/archive/2009/12/02/what-is-administration-config-for-iis.aspx"&gt;Administration.config file&lt;/a&gt; which controls things like Module registration.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;There's one kind of new update to this list - using aspnet.config for Application Pool tuning.&lt;/strong&gt; It's found in the same directory as Machine.config, and it's been around since .NET 2.0. However, as of ASP.NET 4 it's been expanded to handle things like concurrency and threading, as explained in Scott Forsyth's post, &lt;a href="http://weblogs.asp.net/owscott/archive/2011/12/01/setting-an-aspnet-config-file-per-application-pool.aspx"&gt;Setting an aspnet.config File per Application Pool&lt;/a&gt;. While not something most ASP.NET developers will need to use, it's good to know that you can control things like maxConcurrentRequestsPerCPU, maxConcurrentThreadsPerCPU and requestQueueLimit at the application pool level.&lt;/p&gt;  &lt;h2&gt;Tip 4: Location, location&lt;/h2&gt;  &lt;p&gt;While it's nice to be able to override settings in a subfolder using nested Web.config files, that can become hard to manage. In a large application, it can be difficult to manage settings because you can't see the effective permissions in one place. Another option is to use the &lt;a href="http://msdn.microsoft.com/en-us/library/b6x6shw7.aspx"&gt;&amp;lt;location&amp;gt; element&lt;/a&gt; to target settings to a specific location. For example, I previously showed how to use this to &lt;a href="http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx"&gt;allow large file uploads to a specific directory in an ASP.NET application&lt;/a&gt; using the location element:&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;location path=&amp;quot;Upload&amp;quot;&amp;gt;
    &amp;lt;system.web&amp;gt;

        &amp;lt;httpRuntime executionTimeout=&amp;quot;110&amp;quot; 
                     maxRequestLength=&amp;quot;20000&amp;quot; /&amp;gt;
    &amp;lt;/system.web&amp;gt;
&amp;lt;/location&amp;gt;&lt;/pre&gt;

&lt;h2&gt;Tip 5: Clearing parent settings when adding to a collection&lt;/h2&gt;

&lt;p&gt;Sometimes you want to remove all inherited settings and start fresh. A common place you'll see this is in handler, module, connection string and provider registration - places where configuration is used to populate a collection. &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/11/20/common-gotcha-don-t-forget-to-clear-when-adding-providers.aspx"&gt;Scott Guthrie blogged about an example in which just adding a new Membership Provider causes problems&lt;/a&gt;, because you end up with two providers - the default, and the one you just added. &lt;strong&gt;It's important to clear the collection before adding your new provider using the &amp;lt;clear/&amp;gt; element&lt;/strong&gt;, like this:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;membership&amp;gt;
      &amp;lt;providers&amp;gt;
          &amp;lt;clear/&amp;gt;
          &amp;lt;add name=&amp;quot;AspNetSqlMembershipProvider&amp;quot;
              type=&amp;quot;System.Web.Security.SqlMembershipProvider, 
                    System.Web, Version=2.0.0.0, 
                    Culture=neutral, 
                    PublicKeyToken=b03f5f7f11d50a3a&amp;quot;
              connectionStringName=&amp;quot;MyDatabase&amp;quot;
              enablePasswordRetrieval=&amp;quot;false&amp;quot;
              (additional elements removed for brevity)
          /&amp;gt;
      &amp;lt;/providers&amp;gt;
&amp;lt;/membership&amp;gt; &lt;/pre&gt;

&lt;p&gt;As Scott explains, failure to &amp;lt;clear/&amp;gt; the collection first results in both providers attempting to handle membership, which probably isn't what you intended.&lt;/p&gt;

&lt;h2&gt;Tip 6: Locking settings with with allowOverride and inheritInChildApplications&lt;/h2&gt;

&lt;p&gt;You may need to prevent sub-applications from overriding or extending settings. You can do that with the allowOverride attribute, which does exactly what the name suggests - the same way a sealed class prevents changes via a derived class. The &lt;a href="http://msdn.microsoft.com/en-us/library/ms178693.aspx"&gt;MSDN documentation&lt;/a&gt; summarizes this well:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You can lock configuration settings in ASP.NET configuration files (Web.config files) by adding an allowOverride attribute to a location element and setting the allowOverride attribute to false. Then within the location element, you can define the configuration section that you want to lock. ASP.NET will throw an exception if another configuration file attempts to override any configuration section that is defined within this locked location element.&lt;/p&gt;

  &lt;p&gt;Using a location element with an allowOverride=false attribute locks the entire configuration section. You can also lock individual configuration elements and attributes using lockItem, lockElements, lockAttributes, lockAllAttributesExcept, and lockAllElementsExcept.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That last part there - using attributes on sections - works because those lock attributes are among the &lt;a href="http://msdn.microsoft.com/en-us/library/ms228167.aspx"&gt;general attributes inherited by section elements&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;Tip 7: Disinheriting your child applications with inheritInChildApplications=&amp;quot;false&amp;quot;&lt;/h2&gt;

&lt;p&gt;If you've got settings that should only apply to the parent application and shouldn't be inherited, &lt;strong&gt;you can use the inheritInChildApplications attribute&lt;/strong&gt; on any section or location element. That makes the settings at the current level, but inheriting applications and subfolders don't have to bother with clearing and rebuilding configuration just to remove those settings.&lt;/p&gt;

&lt;p&gt;This came up in a recent question on StackOverflow:&amp;#160; &lt;a href="http://stackoverflow.com/questions/8536091/unloading-parts-of-a-web-config-file-from-a-child-application"&gt;Unloading parts of a web.config file from a child application&lt;/a&gt;&lt;/p&gt;

&lt;div id="stacktack-8536091" class="width-800px filterAnswers-8548245"&gt;&lt;/div&gt;
&lt;script type="text/javascript" src="http://app.stacktack.com/jquery.stacktack.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt; 
    $(function() {
        $(document).stacktack();
    });
&lt;/script&gt;

&lt;p&gt;Since Web.config is so heavily built on the concept of inheritance, it's not surprising that turning it off for a section can have some side effects. The aptly self-named &amp;quot;Run Things Proper Harry,&amp;quot; a.k.a. rtpHarry, has written up two good posts covering usage and important things to be aware of.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://runtingsproper.blogspot.com/2010/04/solved-breaking-parent-webconfig.html"&gt;SOLVED: Breaking parent web.config dependencies in sub applications&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://runtingsproper.blogspot.com/2010/04/solved-iis7-validateintegratedmodeconfi.html"&gt;SOLVED: IIS7, validateIntegratedModeConfiguration and inheritInChildApplications clash&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Tip 8: Use configSource to separate configuration into separate files&lt;/h2&gt;

&lt;p&gt;While I've been discussing modification of Web.config settngs through inheritance, it only makes sense to mentions some useful ways to handle overriding Web.config settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Any Web.config section can be moved to a separate file by setting the &lt;/strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.configsource.aspx"&gt;&lt;strong&gt;configSource attribute&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; to a file reference.&lt;/strong&gt; I've mostly used this for handling connection strings, since it allows you a lot more flexibility over versioning and and deployment. Instead of having different Web.config files for each environment (&amp;quot;Oops! Just deployed the staging Web.config to production!!!&amp;quot;). It looks like this:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;configuration&amp;gt;
  &amp;lt;connectionStrings configSource=&amp;quot;connectionStrings.config&amp;quot; /&amp;gt;
  ...&lt;/pre&gt;

&lt;p&gt;Then your connectionStrings.config file only needs to change between environments, and can contain specific settings. It holds the contents of the element you're referring to, so it looks like this:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;connectionStrings&amp;gt;
  &amp;lt;add name=&amp;quot;subtextData&amp;quot;
    connectionString=&amp;quot;Server=.;Database=staging;Trusted_Connection=True;&amp;quot; /&amp;gt;
&amp;lt;/connectionStrings&amp;gt;&lt;/pre&gt;

&lt;p&gt;Another way I've seen this done is to have differently named connection strings config files for each environment (e.g. dev.config, staging.config, production.config). That allows you to check them all in to source control and not worry about getting files with the same name but different contents mixed up, but the tradeoff is that your Web.config in each environment needs to be updated to point to the right config source.&lt;/p&gt;

&lt;p&gt;So, this is a handy trick, but isn't quite perfect. A better option is to use Web.config File Transformations.&lt;/p&gt;

&lt;h2&gt;Tip 9: Use Web.config Transforms to handle environmental differences&lt;/h2&gt;

&lt;p&gt;I don't hear as much about Web.config Transforms as I'd expect. Maybe they just work and everyone just quietly uses them and doesn't talk about it. But from the questions I see coming up over and over again, I'm not sure that's the case.&lt;/p&gt;

&lt;p&gt;I love Web.config Transforms. At my first ASP.NET MVP summit, I was part of a feedback group discussing frustrations with deploying ASP.NET applications. Two themes that came up over and over were difficulties with packaging and managing configuration. That team later produced Web Deployment Packages (a nice format that packages files and settings for a site in a way that can be inspected and modified during installation) and Web.config Transforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All the new ASP.NET projects have Web.config transforms already set up&lt;/strong&gt; - if you expand the Web.config node, you'll see that it's configured to create different settings for Debug and Release mode.&lt;/p&gt;

&lt;p&gt;&lt;a title="2012-01-17 14h51_29" href="http://www.flickr.com/photos/36836555@N00/6716902571/"&gt;&lt;img border="0" alt="2012-01-17 14h51_29" src="http://farm8.static.flickr.com/7015/6716902571_bc4864fc6c_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's really easy to use - &lt;strong&gt;your main Web.config has the base settings for your site, and whenever you build, the transforms for the appropriate build configuration (e.g. Debug or Release) are automatically applied&lt;/strong&gt;. If you had a Test database that you wanted to use by default, but wanted your Release builds to run against the Production database, you could set it up so that your base Web.config connection string points to the Test Database connection string, like this:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;connectionStrings&amp;gt;
  &amp;lt;add name=&amp;quot;ApplicationServices&amp;quot;
      connectionString=&amp;quot;[TestDatabase]&amp;quot; /&amp;gt;
&amp;lt;/connectionStrings&amp;gt;&lt;/pre&gt;

&lt;p&gt;Then your Web.Release.config overwrites that to point at the Production database, like this:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;configuration xmlns:xdt=&amp;quot;http://schemas.microsoft.com/XML-Document-Transform&amp;quot;&amp;gt;
  &amp;lt;connectionStrings&amp;gt;
    &amp;lt;add name=&amp;quot;ApplicationServices&amp;quot; 
        connectionString=&amp;quot;[ProductionDatabase]&amp;quot; 
        xdt:Transform=&amp;quot;Replace&amp;quot; xdt:Locator=&amp;quot;Match(name)&amp;quot;/&amp;gt;
  &amp;lt;/connectionStrings&amp;gt;
&amp;lt;/configuration&amp;gt;&lt;/pre&gt;

&lt;p&gt;The syntax is pretty straightforward, but you don't need to worry about that because the comments in the Web.Release.config file already show how to do that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To be clear: unlike the other examples, this is something that happens at build time, not runtime.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I recently ran into an issue where I wanted to deploy something to AppHarbor and wanted to switch between a local SQL Compact database and the hosted database server, and Web.config Transforms worked just great there.&lt;/p&gt;

&lt;p&gt;There's a lot more to talk about with Web.config Transforms that's beyond the scope here, such as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can &lt;strong&gt;create as many build configurations as you want&lt;/strong&gt;, with different transforms for each configuration. This makes it simple to switch between different settings in your development environment - say, switching between several development databases or other application settings. &lt;/li&gt;

  &lt;li&gt;You can &lt;strong&gt;use the configuration transformation system&lt;/strong&gt; with any XML file using the &lt;a href="http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5"&gt;SlowCheetah Visual Studio extension&lt;/a&gt;. Scott Hanselman's written a post with more information on that here: &lt;a href="http://www.hanselman.com/blog/SlowCheetahWebconfigTransformationSyntaxNowGeneralizedForAnyXMLConfigurationFile.aspx"&gt;SlowCheetah - Web.config Transformation Syntax now generalized for any XML configuration file&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Sayed (the Microsoft developer who's worked on both Web.config Transforms and the SlowCheetah extension) has also built a &lt;a href="http://sedodream.com/2011/12/24/PackageOncePublishAnywhere.aspx"&gt;Package Once Publish Anywhere&lt;/a&gt; NuGet package which allows you to &lt;strong&gt;defer running the transforms until later, using a PowerShell command&lt;/strong&gt;. That means you can build one Web Deployment Package with all the transforms included, and run them when you're going to deploy to a specific environment. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's some good information on MSDN about Web.config Transforms:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/"&gt;Web.config File Transformation&lt;/a&gt; section in the Web Application Project Deployment Overview &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd465326.aspx"&gt;Web.config Transformation Syntax for Web Application Project Deployment&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Scott Hanselman: &lt;a href="http://www.hanselman.com/blog/WebDeploymentMadeAwesomeIfYoureUsingXCopyYoureDoingItWrong.aspx"&gt;Web Deployment Made Awesome: If You're Using XCopy, You're Doing It Wrong&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Tip 10: Managing Application Restarts on Configuration Changes&lt;/h2&gt;

&lt;p&gt;There are a lot of moving parts in figuring out the configuration for a website, as illustrated above. For that reason, ASP.NET computes the effective settings for the site and caches them. It only recomputes them (and restarts the application) when a file in the sites configuration hierarchy is modified. You can control that on a section by section level using the &lt;a href="http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.restartonexternalchanges.aspx"&gt;restartOnExternalChanges property&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One place where configuration changes don't automatically get recomputed is for external config files set using configSource (as shown in Tip 8). You can control that by &lt;a href="http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.configsource.aspx"&gt;setting restartOExternalChanges=&amp;quot;true&amp;quot; for that section&lt;/a&gt;. There's an &lt;a href="http://msdn.microsoft.com/en-us/library/ms228057.aspx"&gt;example on MSDN&lt;/a&gt; that shows this in more detail by creating an external configuration file which is loaded via the configuration API (not referenced via configSource), then toggling the restartOnExternalChanges property and showing the differences in operation.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;The ASP.NET Configuration system does quite a bit - I didn't even mention big topics like using the API for reading and writing values to both local and external config files or creating custom configuration sections. This post focuses on one aspect: getting things done by understanding and leveraging inheritance and overrides. Hopefully this gives you both some new tools for effectively handling configuration and some background that helps in troubleshooting when configuration is working as you'd like.&lt;/p&gt;

&lt;p&gt;Are there any essential tips that I missed?&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8261171" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=JHXpr59NjP8:2S-xADi5WGQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=JHXpr59NjP8:2S-xADi5WGQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=JHXpr59NjP8:2S-xADi5WGQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=JHXpr59NjP8:2S-xADi5WGQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=JHXpr59NjP8:2S-xADi5WGQ:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=JHXpr59NjP8:2S-xADi5WGQ:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=JHXpr59NjP8:2S-xADi5WGQ:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/JHXpr59NjP8" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/ASP.NET/default.aspx">ASP.NET</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2012/01/17/10-things-asp-net-developers-should-know-about-web-config-inheritance-and-overrides.aspx</feedburner:origLink></item><item><title>Excerpt Old Posts - A WordPress Plugin to get around the Feedburner 512K Limit</title><link>http://feedproxy.google.com/~r/jongalloway/~3/HLPYkvbSt8E/excerpt-old-posts-a-wordpress-plugin-to-get-around-the-feedburner-512k-limit.aspx</link><pubDate>Sat, 07 Jan 2012 01:24:01 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8229635</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8229635</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2012/01/06/excerpt-old-posts-a-wordpress-plugin-to-get-around-the-feedburner-512k-limit.aspx#comments</comments><description>&lt;h1&gt;Summary&lt;/h1&gt;  &lt;p&gt;If you've got a WordPress blog and use Feedburner, you may notice that the posts stop updating. It's often due to a limitation on Feedburner that stops updating if your feed exceeds 512K. I wrote a simple plugin called &lt;a href="http://wordpress.org/extend/plugins/excerpt-old-posts/"&gt;Excerpt Old Posts&lt;/a&gt; that fixes that problem by showing Full Text for recent posts and Summary for older posts.&lt;/p&gt;  &lt;h1&gt;Background&lt;/h1&gt;  &lt;p&gt;I run a podcast website (&lt;a href="http://herdingcode.com/"&gt;Herding Code podcast&lt;/a&gt;) on WordPress. The feed's probably the most important part of that site, since it's how people subscribe, feeds into iTunes and other podcast directories, etc. We put some work into the show notes, so I definitely want full text for each post in the feed. For users who just find the podcast, I want them to be able to find all our episodes in iTunes or other feed sources. I want a full feed - all text for all the posts.&lt;/p&gt;  &lt;p&gt;We use Feedburner for some advanced feed management features, especially&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Podcast support (it handles all the funky iTunes tags) &lt;/li&gt;    &lt;li&gt;Tracking and analytics &lt;/li&gt;    &lt;li&gt;Ability to change hosting without breaking the feed &lt;/li&gt;    &lt;li&gt;Probably some other stuff I'm forgetting about - I've been using Feedburner for a long time &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;The Feedburner 512K feed limit&lt;/h1&gt;  &lt;p&gt;Unfortunately, Feedburner's got a limit of 512K per feed. If you exceed that limit, the feed just stops updating. I've run into this several times - I'd post a new show, and it wouldn't show up in Feedburner. I'd go through the standard Feedburner troubleshooting steps:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Manually &lt;a href="http://www.feedburner.com/fb/a/ping"&gt;ping Feedburner&lt;/a&gt; to make sure it knew there was something new &lt;/li&gt;    &lt;li&gt;Check the Feedburner Troubleshootize page, which would lie to me tell me my feed was &amp;quot;quite healthy.&amp;quot; &lt;/li&gt;    &lt;li&gt;Eventually I'd give up and just Resync the feed (the so-called nuclear option) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Finally, when I'd attempt to Resync, Feedburner would tell me what was wrong - the feed was too big: &amp;quot;&lt;em&gt;Feed Error: Your Feed Filesize is Larger than 512K&lt;/em&gt;&amp;quot;&lt;/p&gt;  &lt;p&gt;There are two problems here:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://support.google.com/feedburner/bin/answer.py?hl=en&amp;amp;answer=79009"&gt;Feedburner has a feed size limit at 512K&lt;/a&gt; (note - just the textual feed, this doesn't count the linked media like podcast MP3's) &lt;/li&gt;    &lt;li&gt;They don't tell you when you exceed that limit &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;No compliants on the first problem, Feedburner probably needs to set some limits on feed size or they'd grow like crazy. The big problem is that there's no notification, even in the admin interface, until you try to resync the feed.&lt;/p&gt;  &lt;h1&gt;My first (lame) solution: Compromise on quantity or quality&lt;/h1&gt;  &lt;p&gt;If you search around, you'll see that's the common suggestion - go in to to the &lt;a href="http://codex.wordpress.org/Settings_Reading_Screen"&gt;Reading settings&lt;/a&gt; and either change the feed to show a summary for each post, or limit the number of items in the feed.&lt;/p&gt;  &lt;p&gt;That solves the problem, but it doesn't make me - or our listeners - happy. As I explained above, everyone wants the Full Text for new content, and new subscribers want to see all shows listed when they subscribe.&lt;/p&gt;  &lt;p&gt;What I really want is a feed that has Full Text for most of our newest posts and Summary for our old posts. That lead me to a slightly better solution.&lt;/p&gt;  &lt;h1&gt;My second (slightly less lame) solution: Hack around in feeds-rss2.php&lt;/h1&gt;  &lt;p&gt;After a while, decided to dig around and find out where the feed was actually written out. I found that my RSS feed was being written out in feeds-rss2.php, and wrote some ugly but workable code that runs a simple counter and switches from full posts to summaries after the counter hits a threshold. If you need that modified feeds-rss2.php for some reason, it's &lt;a href="https://gist.github.com/1573203"&gt;here&lt;/a&gt;. I hope you don't use it, though, because there's a problem: the next time I updated to the newest version of WordPress, my feed broke again.&lt;/p&gt;  &lt;h1&gt;My third (best) solution: Wrap this logic up in a plugin&lt;/h1&gt;  &lt;p&gt;Of course, the problem with tweaking internal code is that it gets overwritten when you update. The right way to extend WordPress is to create a plugin. That way your changes are all wrapped up nicely in a way that survives updates. And, also nice, the changes are easy to share with others.&lt;/p&gt;  &lt;p&gt;This was my first WordPress plugin, and I'll save that process for another post. The important thing is that the plugin's got the &lt;a href="http://www.codinghorror.com/blog/2007/03/the-works-on-my-machine-certification-program.html"&gt;Works On My Machine certification&lt;/a&gt; and is up in the WordPress Plugins Directory, titled &lt;a href="http://wordpress.org/extend/plugins/excerpt-old-posts/"&gt;Excerpt Old Posts&lt;/a&gt;. Yes, that's a kind of boring name.&lt;/p&gt;  &lt;p&gt;It's pretty easy to use:&lt;/p&gt;  &lt;h2&gt;Add the Plugin in the &lt;a href="http://codex.wordpress.org/Managing_Plugins#Installing_Plugins"&gt;WordPress Plugin settings&lt;/a&gt;:&lt;/h2&gt;  &lt;p&gt;In your admin settings, Go to Plugins / Add New. Click on Search and type in &amp;quot;Excerpt Old Posts&amp;quot;&lt;/p&gt;  &lt;p&gt;Install the plugin and activate it.&lt;/p&gt;  &lt;p&gt;Actually, that's really all you have to do if you want the default number of full posts (50) in your feed. You can check your feed if you'd like - you should now see that the 50 most recent items are showing Full Text, and the older ones are just showing the short Summary.&lt;/p&gt;  &lt;h2&gt;Changing the number of full posts shown in your feed&lt;/h2&gt;  &lt;p&gt;There's just one new setting available - the number of Full Text posts you'd like in your feed. Rather than adding a new settings page, I extended the Reading page. It seemed simpler to me - if I end up adding more settings I'll set up a new settings page for the plugin. You can see the new setting below:&lt;/p&gt;  &lt;p&gt;&lt;a title="WordPress - Excerpt Old Posts" href="http://www.flickr.com/photos/36836555@N00/6631903357/"&gt;&lt;img border="0" alt="WordPress - Excerpt Old Posts" src="http://farm8.static.flickr.com/7168/6631903357_ecdf23b5c3_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That's it, hope you like it. &lt;strong&gt;If you have problems, I'd recommend using the &lt;/strong&gt;&lt;a href="http://wordpress.org/tags/excerpt-old-posts?forum_id=10"&gt;&lt;strong&gt;dedicated forum for this plugin&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; rather than the comments on this post&lt;/strong&gt;, as you're more likely to get a timely response.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8229635" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=HLPYkvbSt8E:QO0ZKjEYt88:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=HLPYkvbSt8E:QO0ZKjEYt88:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=HLPYkvbSt8E:QO0ZKjEYt88:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=HLPYkvbSt8E:QO0ZKjEYt88:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=HLPYkvbSt8E:QO0ZKjEYt88:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=HLPYkvbSt8E:QO0ZKjEYt88:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=HLPYkvbSt8E:QO0ZKjEYt88:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/HLPYkvbSt8E" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/Blogging/default.aspx">Blogging</category><category domain="http://weblogs.asp.net/jgalloway/archive/tags/WordPress/default.aspx">WordPress</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2012/01/06/excerpt-old-posts-a-wordpress-plugin-to-get-around-the-feedburner-512k-limit.aspx</feedburner:origLink></item><item><title>My wife and I recorded a Christmas song: Twelve Days of the Partridge</title><link>http://feedproxy.google.com/~r/jongalloway/~3/oyXkd-7r2I8/my-wife-and-i-recorded-a-christmas-song-twelve-days-of-the-partridge.aspx</link><pubDate>Sun, 25 Dec 2011 20:58:55 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8172405</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8172405</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/12/25/my-wife-and-i-recorded-a-christmas-song-twelve-days-of-the-partridge.aspx#comments</comments><description>&lt;p&gt;Since 2007, my wife and I have been contributing a song to the &lt;a href="http://familyrechristmas.bandcamp.com"&gt;Familyre Christmas compilation albums&lt;/a&gt;. You can download &lt;a href="http://familyrechristmas.bandcamp.com/releases"&gt;this year's for free&lt;/a&gt;, and you can play them all online on Bandcamp. My wife had written original songs each previous year; this year I suggested we just record a classic like The Twelve Days of Christmas.&lt;/p&gt;  &lt;p&gt;You can stream or download our song - Twelve Days of the Partridge - here (perhaps while reading this post):&lt;/p&gt;  &lt;p&gt;&lt;iframe style="position: relative; width: 403px; display: block; height: 100px" height="100" src="http://bandcamp.com/EmbeddedPlayer/v=2/track=3857975050/size=venti/bgcol=FFFFFF/linkcol=4285BB/" frameborder="0" width="400" allowtransparency="allowtransparency"&gt;&lt;a href="http://familyrechristmas.bandcamp.com/track/rachel-and-jon-galloway-twelve-days-of-the-partridge"&gt;Rachel and Jon Galloway - Twelve Days of the Partridge by Sounds Familyre&lt;/a&gt;&lt;/iframe&gt;&lt;/p&gt;  &lt;p&gt;You can stream or download the full album here:&lt;iframe style="position: relative; width: 400px; display: block; height: 100px" height="100" src="http://bandcamp.com/EmbeddedPlayer/v=2/album=1878832640/size=venti/bgcol=FFFFFF/linkcol=4285BB/" frameborder="0" width="400" allowtransparency="allowtransparency"&gt;&lt;a href="http://familyrechristmas.bandcamp.com/album/a-familyre-christmas-volume-4"&gt;A Familyre Christmas - Volume 4 by Sounds Familyre&lt;/a&gt;&lt;/iframe&gt;&lt;/p&gt;  &lt;h2&gt;Twelve Days: trickier than you'd think&lt;/h2&gt;  &lt;p&gt;I originally suggested Twelve Days of Christmas so we could just take it easy this year; I probably should have thought about that a bit first. As an old traditional song, The Twelve Days of Christmas has an interesting song structure. It bounces between 4/4 and 3/4 time, with some pickup notes just to mix things up a bit. It's odd enough that &lt;a href="http://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)#Structure"&gt;Wikipedia actually has a section talking about the song structure, irregular meter&lt;/a&gt;, and other things that give electronic recording people headaches:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;The &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Time_signature"&gt;&lt;em&gt;time signature&lt;/em&gt;&lt;/a&gt;&lt;em&gt; of this song is not constant, unlike most popular music. This irregular &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Meter_(music)"&gt;&lt;em&gt;meter&lt;/em&gt;&lt;/a&gt;&lt;em&gt; perhaps speaks for the song's &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Folk_song"&gt;&lt;em&gt;folk&lt;/em&gt;&lt;/a&gt;&lt;em&gt; origin. The introductory lines, such as &amp;quot;On the twelfth day of Christmas, my true love gave to me&amp;quot;, are made up of two 4/4 &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Bar_(music)"&gt;&lt;em&gt;bars&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, while most of the lines naming gifts receive one 3/4 bar per gift with the exception of &amp;quot;Five gold(en) rings,&amp;quot; which receives two 4/4 bars, &amp;quot;Two turtle doves&amp;quot; getting a 4/4 bar with &amp;quot;And a&amp;quot; on its 4th beat and &amp;quot;Partridge in a pear tree&amp;quot; getting two 4/4 bars of music. In most versions, a 4/4 bar of music immediately follows &amp;quot;Partridge in a pear tree.&amp;quot; &amp;quot;On the&amp;quot; is found in that bar on the 4th (pickup) beat for the next verse. The successive bars of 3 for the gifts surrounded by bars of 4 give the song its hallmark &amp;quot;hurried&amp;quot; quality.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;The second to fourth verses' melody is different from that of the fifth to twelfth verses. Before the fifth verse (when &amp;quot;five gold(en) rings&amp;quot; is first sung), the melody, using &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Solfege"&gt;&lt;em&gt;solfege&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, is &amp;quot;sol re mi fa re&amp;quot; for the fourth to second items, and this same melody is thereafter sung for the twelfth to sixth items. However, the melody for &amp;quot;four colly birds, three French hens, two turtle doves&amp;quot; changes from this point, differing from the way these lines were sung in the opening four verses.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;Credits and stuff&lt;/h2&gt;  &lt;p&gt;My wife Rachel did most of the work on this one: singing, acoustic guitar, ukulele, flute, xylophone.&lt;/p&gt;  &lt;p&gt;I played bass, organ, electronic drums (most of which I decided to remove in the mix), and ran most of the recording and mixing. My favorite part was the organ - I used my brother Glen's Nord Electro 2 on a drawbar organ setting with an auto-wah. I love that sound.&lt;/p&gt;  &lt;p&gt;We had a bunch of help from our friends:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.facebook.com/briankgalloway"&gt;Brian Galloway&lt;/a&gt; provided some tasty electronic guitar licks. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.facebook.com/people/John-Ciccolella/533487931"&gt;John Ciccolella&lt;/a&gt; hooked us up with some awesome fiddling (and help with the arrangement). &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.facebook.com/profile.php?id=10503195"&gt;Andrew Smith&lt;/a&gt; did the work of twelve men (twelve drummers drumming) &lt;/li&gt;    &lt;li&gt;Our daughters and friends sang the children's choir bit on the 12th day. &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Nerdy recording stuff&lt;/h2&gt;  &lt;p&gt;I decided to do the editing and mixing in Audacity. It's picked up a lot of features over the past few years that really helped, including track groups, envelopes, and solid VST effect support. We ended up with a few dozen live tracks, so there were two main jobs in the mix - fixing little timing issues to tighten it up, and getting the levels right so all the parts were audible.&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-12-25 11h54_27" href="http://www.flickr.com/photos/36836555@N00/6570663041/"&gt;&lt;img border="0" alt="2011-12-25 11h54_27" src="http://farm8.static.flickr.com/7149/6570663041_b3143e5d54_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Handling timing&lt;/h3&gt;  &lt;p&gt;With a big song like this, a click track is a must. I also made use of a nice plugin called &lt;a href="http://audacity.sourceforge.net/download/nyquistplugins"&gt;Regular Interval Labels&lt;/a&gt; to visually align audio clips. The big benefit that it provides is that the clips snap to nearest labels a bit, so it's much easier to align them.&lt;/p&gt;  &lt;h3&gt;Handling volume&lt;/h3&gt;  &lt;p&gt;For a mix like this, the trick is to make everything audible without clipping. The trap is to avoid saying &amp;quot;Hmm, can't hear the second violin track, better turn it up.&amp;quot; Instead, I focus on listening for which tracks can be turned down and still be audible. For a dynamic mix which responds to new instruments joining part way through the song, I really rely on the volume envelopes:&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-12-25 12h07_46" href="http://www.flickr.com/photos/36836555@N00/6570678507/"&gt;&lt;img border="0" alt="2011-12-25 12h07_46" src="http://farm8.static.flickr.com/7027/6570678507_b61cba6cd2_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;VST Plugins&lt;/h3&gt;  &lt;p&gt;I made some electronic drum loops which sounded cool in parts, but it was a pretty busy mix and we ended up pulling most of them out. Rachel and I joked around with putting one halfway through the song, as a brief intermission. It cracked us up, so we decided to keep it. The problem was that it kind of jumped out since it was really punchy, so we ended up thinning it out so it sounded like an old record. We used &lt;a href="http://www.izotope.com/products/audio/vinyl/"&gt;iZotope Vinyl&lt;/a&gt; (free), a classic EQ setting, and &lt;a href="http://illformed.org/plugins/"&gt;dBlue Tape Stop&lt;/a&gt; effect (also free). I made the loop in FL Studio Pro - it's intentionally a little out of time so it sounds more natural.&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-12-25 12h40_33" href="http://www.flickr.com/photos/36836555@N00/6570837875/"&gt;&lt;img border="0" alt="2011-12-25 12h40_33" src="http://farm8.static.flickr.com/7154/6570837875_eaea6b05ae_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Last year's track - Glory&lt;/h2&gt;  &lt;p&gt;If you like this one, you might like the song we did last year:&lt;/p&gt; &lt;iframe style="position: relative; width: 400px; display: block; height: 100px" height="100" src="http://bandcamp.com/EmbeddedPlayer/v=2/track=1384545553/size=venti/bgcol=FFFFFF/linkcol=4285BB/" frameborder="0" width="400" allowtransparency="allowtransparency"&gt;&lt;a href="http://familyrechristmas.bandcamp.com/track/glory"&gt;Glory by Rachel and Jon Galloway&lt;/a&gt;&lt;/iframe&gt;  &lt;p&gt;Merry Christmas!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8172405" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=oyXkd-7r2I8:vgVZ7ryzI4Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=oyXkd-7r2I8:vgVZ7ryzI4Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=oyXkd-7r2I8:vgVZ7ryzI4Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=oyXkd-7r2I8:vgVZ7ryzI4Q:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=oyXkd-7r2I8:vgVZ7ryzI4Q:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=oyXkd-7r2I8:vgVZ7ryzI4Q:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=oyXkd-7r2I8:vgVZ7ryzI4Q:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/oyXkd-7r2I8" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/12/25/my-wife-and-i-recorded-a-christmas-song-twelve-days-of-the-partridge.aspx</feedburner:origLink></item><item><title>Working around a Powershell Call Depth Disaster With Trampolines</title><link>http://feedproxy.google.com/~r/jongalloway/~3/sNOoGkNHcuw/working-around-a-powershell-call-depth-disaster-with-trampolines.aspx</link><pubDate>Thu, 15 Dec 2011 23:03:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8129074</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8129074</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/12/15/working-around-a-powershell-call-depth-disaster-with-trampolines.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/12/14/nuget-powershell-downloader-update-adding-failed-download-retries-better-paging-support.aspx"&gt;I just posted about an update to my NuGet package downloader script which included a few fixes, including a fix to handle paging&lt;/a&gt;. That sounds boring, but wait until you hear about the trampolines.&lt;/p&gt;  &lt;h2&gt;Recursion: Seemed like a good idea at the time&lt;/h2&gt;  &lt;p&gt;The whole idea of this script is to download package files referenced in the public NuGet package feed. The NuGet package is in OData format, and it's paged. That's a good thing - requesting the feed shouldn't make you wait while up to 16,000 (and growing) package descriptions are downloaded, and it shouldn't tie up the server with that either. Each page currently returns 100 items, but that's a service implementation detail that could change at any time.&lt;/p&gt;  &lt;p&gt;Paging in OData is done using a &amp;lt;link rel=&amp;quot;next&amp;quot; href=&amp;quot;http://url.com?$skiptoken=sometoken&amp;gt; element at the end of each page, like this:&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;iso-8859-1&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;
&amp;lt;feed xml:base=&amp;quot;http://packages.nuget.org/v1/FeedService.svc/&amp;quot; xmlns:d=&amp;quot;http://schemas.microsoft.com/ado/2007/08/dataservices&amp;quot; 
xmlns:m=&amp;quot;http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&amp;quot; xmlns=&amp;quot;http://www.w3.org/2005/Atom&amp;quot;&amp;gt;
  &amp;lt;title type=&amp;quot;text&amp;quot;&amp;gt;Packages&amp;lt;/title&amp;gt;
  &amp;lt;id&amp;gt;http://packages.nuget.org/v1/FeedService.svc/Packages&amp;lt;/id&amp;gt;
  &amp;lt;updated&amp;gt;2011-12-08T23:46:46Z&amp;lt;/updated&amp;gt;
  &amp;lt;link rel=&amp;quot;self&amp;quot; title=&amp;quot;Packages&amp;quot; href=&amp;quot;Packages&amp;quot; /&amp;gt;

  &amp;lt;entry&amp;gt;
    &amp;lt;id&amp;gt;http://packages.nuget.org/v1/FeedService.svc/Packages(Id='adjunct-Some.Package',Version='1.0.0.0')&amp;lt;/id&amp;gt;
    &amp;lt;title type=&amp;quot;text&amp;quot;&amp;gt;Some.Package&amp;lt;/title&amp;gt;
    &amp;lt;summary type=&amp;quot;text&amp;quot;&amp;gt;First!!!! w00t!!!&amp;lt;/summary&amp;gt;
    &amp;lt; more stuff here /&amp;gt;
  &amp;lt;/entry&amp;gt;
  &amp;lt;entry&amp;gt;
    &amp;lt; ... entry stuff for another package ... /&amp;gt;
  &amp;lt;/entry&amp;gt;

  &amp;lt; etc - 98 more entry elements /&amp;gt;

  &amp;lt;entry&amp;gt;
    &amp;lt;id&amp;gt;http://packages.nuget.org/v1/FeedService.svc/Packages(Id='adjunct-Last.On.The.Page',Version='1.0.0.0')&amp;lt;/id&amp;gt;
    &amp;lt;title type=&amp;quot;text&amp;quot;&amp;gt;Last.On.The.Page&amp;lt;/title&amp;gt;
    &amp;lt;summary type=&amp;quot;text&amp;quot;&amp;gt;Last package on the first page&amp;lt;/summary&amp;gt;
    &amp;lt; more stuff here /&amp;gt;
  &amp;lt;/entry&amp;gt;
  
  &amp;lt;link rel=&amp;quot;next&amp;quot; href=&amp;quot;http://packages.nuget.org/v1/FeedService.svc/Packages?$skiptoken='adjunct-Last.On.The.Page','1.0.0.0'&amp;quot; /&amp;gt;
&amp;lt;/feed&amp;gt;&lt;/pre&gt;

&lt;p&gt;The important bit is that the link element tells you how to request the next page of information. Here it's a link to the same feed with a skip token indicating the last item we've seen. I'm simplifying this a bit - the feed also handles searching, ordering, etc., but I'm just focusing on the paging bit. If you make a big request, the server returns you a chunk of the results with a link to get the next chunk.&lt;/p&gt;

&lt;p&gt;My original implementation was to do something like this:&lt;/p&gt;

&lt;pre class="brush: ps; auto-links: false;"&gt;function DownloadEntries {
 param ([string]$feedUrl) 

    // Download all items on the page
    
    $nextUrl = href from last link on the page
    
    DownloadEntries $nextUrl
}

DownloadEntries $firstPage&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Note: If you're new to PowerShell, that's the syntax for writing a function called DownloadEntries which takes a string parameter called feedUrl.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So DownloadEntries gets passed a URL, downloads all entries on that page, and calls itself with the URL to the next page in the list. This works just fine for a while, but the problem is that every page is adding another level to the recursive depth of the call graph, meaning we'll run into trouble soon.&lt;/p&gt;

&lt;h2&gt;Recursion, Call Stacks, and Stack Overflows&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Note: I know I'm going to get &lt;/em&gt;&lt;a href="http://tirania.org/blog/archive/2011/Feb-17.html"&gt;&lt;em&gt;#wellactually&lt;/em&gt;&lt;/a&gt;&lt;em&gt;'d to death. I'm bracing for it. I'm not a Recursion Expert of Recursions, and if you are I'm sure I'll hear about it in the comments. Also, you're a big, mean jerk. Actually, I'm happy to learn more, so fire away. Now with that out of the way...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The most common example of recursion in computer science is when a function calls itself. I first stumbled across it as a junior programmer, when I &amp;quot;re-invented&amp;quot; it to solve a tricky problem. I needed to generate a massive Word document report based on a complex object model, and eventually came up with a function that took a node object, wrote out that node's report information, and called itself for each child node. It worked, and when my boss said, &amp;quot;Hey, nice use of recursion!&amp;quot; I hurried off to read what he was talking about.&lt;/p&gt;

&lt;p&gt;Recursion can be really useful, but things can get out of hand. In stack-based languages, recursion requires maintaining the state for everything in the call stack. That means that the memory used by a function grows with the recursion call depth. Since memory is limited, it's easy to write code that will exhaust your available memory, and you'll get a dreaded stack overflow error. Wikipedia lists &lt;a href="http://en.wikipedia.org/wiki/Stack_overflow#Infinite_recursion"&gt;infinite recursion as the most common cause of stack overflows&lt;/a&gt;, but you don't actually have to get all the way to infinity to run out of memory - a lot of recursion is enough.&lt;/p&gt;

&lt;h2&gt;PowerShell's Call Depth Limit&lt;/h2&gt;

&lt;p&gt;Rather than wait for a stack overflow to happen - or even for a script to use up an obscene amount of memory - &lt;a href="http://msdn.microsoft.com/en-us/library/system.management.automation.scriptcalldepthexception(VS.85).aspx"&gt;PowerShell caps the call depth at 100&lt;/a&gt;. That means that, even if there were no memory overhead to each call, the above function would fail at 100 pages. &lt;a href="http://www.dougfinke.com/blog/index.php/2007/05/12/not-tail-recursive/"&gt;Doug Finke shows a very easy way to demonstrate this&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;function simpleTest ($n)
{
    if($n -ne 0) { $n; simpleTest ($n-1) }
}

PS C:\&amp;gt; simpleTest 10
10
9
8
7
6
5
4
3
2
1

PS C:\&amp;gt; simpletest 99
99
98
97
96
95

The script failed due to call depth overflow. 
The call depth reached 101 and the maximum is 100.&lt;/pre&gt;

&lt;h3&gt;Side Note: PowerShell has the same call depth limit (100) on x64 and x86&lt;/h3&gt;

&lt;p&gt;Also from Doug's post: &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Recursion depth limit is fixed in version 1. Deep recursion was causing problems in 64bit mode because of the way exceptions were being processed. It was causing cascading out-of-memory errors. The net result was that we hard-limited the recursion depth on all platforms to help ensure that scripts would be portable to all platforms.&lt;/em&gt; 

    &lt;br /&gt;- Bruce Payette, co-designer of PowerShell&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Tail-Recursive Calls and Trampolines&lt;/h2&gt;

&lt;p&gt;There are ways to work around this problem, but to me they all seem to boil down to replacing deep call stacks with loops - either automatically at the language level or via fancy pants programming. In my case, I needed to convert from recursion to trampoline style - albeit a very simple conversion. With the disclaimer that I'm not an expert here, I thought I'd overview what I read about trampolines, then simplify it down to the basic trampoline solution I ended up with.&lt;/p&gt;

&lt;h3&gt;Tail Call Optimization&lt;/h3&gt;

&lt;p&gt;In some cases, languages can optimize their way around this problem. One example is tail call optimization. A tail call is a call which is happening immediately prior to returning from the function, meaning that there's no remaining logic in the calling function and thus no need to retain the stack. In a tail-recursive call, it's returning that value to itself. &lt;/p&gt;

&lt;p&gt;Languages can effectively unroll this, since in a tail call situation they don't need to maintain the nested call stack as the calling function has completed all its logical operation. If you're using one of those languages and make sure that your recursive calls are tail-recursive (so no additional logic is performed after the recursive call), the language will handle this for you and you'll end up with the benefits of recursion without the baggage of building a big call stack.&lt;/p&gt;

&lt;p&gt;Matthew Podwysocki runs through this in &lt;a href="http://weblogs.asp.net/podwysocki/archive/2008/07/07/recursing-into-linear-tail-and-binary-recursion.aspx"&gt;more detail with a comparison of how this works in F# and C#&lt;/a&gt; (with an interesting difference between 32 and 64 bit operation). He shows an example of a case where a single line of code after the recursive call breaks the tail call optimization, resulting in a stack overflow. &lt;/p&gt;

&lt;p&gt;It's interesting to note that &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.tailcall.aspx"&gt;the common language runtime supports tail calls&lt;/a&gt;, so it comes down to whether the language and compiler make use of it. PowerShell doesn't support tail call optimization, so I needed to alter my code. That's where I learned about trampolines.&lt;/p&gt;

&lt;h3&gt;Trampolines&lt;/h3&gt;

&lt;p&gt;The common pattern I read about for dealing with this is to manage state yourself using &lt;a href="http://en.wikipedia.org/wiki/Tail-recursive_function#Through_trampolining"&gt;a trampoline: a piece of code that repeatedly calls functions&lt;/a&gt;. And, depending on the language and recursive requirements, that little &amp;quot;a piece of code that repeatedly calls functions&amp;quot; can get really pretty complex.&lt;/p&gt;

&lt;p&gt;If my implementation was really making deep use of recursion in such a way that I really needed to emulate nested calls, that trampoline implementation would need to be pretty sophisticated. While that's implemented differently in different languages, in modern .NET programming I'm reading that's usually done using a function factory trampoline class which calls functions for you. Here are some posts showing how to do that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.claassen.net/geek/blog/2010/07/don%e2%80%99t-blow-your-stack-c-trampolining.html"&gt;Don’t blow your stack: C# trampolining&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blog.functionalfun.net/2008/04/bouncing-on-your-tail.html"&gt;Bouncing on your tail&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://tomlev2.wordpress.com/2011/09/02/tail-recursion-in-c/"&gt;Tail recursion in C#&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://bartdesmet.net/blogs/bart/archive/2009/11/08/jumping-the-trampoline-in-c-stack-friendly-recursion.aspx"&gt;Jumping the Trampoline in C# - Stack-Friendly Recursion&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my simple case, though, I could just to convert the recursive call so that it's called from a looping construct, returning state from each call. I'd call this option a strategic retreat, since this is now in no way recursive anymore. But, by calling it a refactoring to implement trampoline-style programming, I'll still keep my pride.&lt;/p&gt;

&lt;p&gt;Less Talk, More Code&lt;/p&gt;

&lt;p&gt;Right.&lt;/p&gt;

&lt;p&gt;So since the reason I was using recursion was just to continue calling the next page after completing the work on the current one, my trampoline can be implemented as a simple for loop into a function that returns the URL of the next page. Remembering that we started with something like this:&lt;/p&gt;

&lt;pre class="brush: ps; auto-links: false;"&gt;function DownloadEntries {
 param ([string]$feedUrl) 

    // Download all items on the page
    
    $nextUrl = href from last link on the page
    
    DownloadEntries $nextUrl
}

DownloadEntries $firstPage&lt;/pre&gt;

&lt;p&gt;We can rewrite that as this:&lt;/p&gt;

&lt;pre class="brush: ps; auto-links: false;"&gt;function DownloadEntries {
 param ([string]$feedUrl) 

    // Download all items on the page
    
    $nextUrl = href from last link on the page
    
    return $nextUrl
}

while($feedUrl -ne $null) {
    $feedUrl = DownloadEntries $feedUrl
}&lt;/pre&gt;

&lt;p&gt;This can now handle unlimited pages, since it's just a simple loop. The only downside is that I can no longer feel quite as sophisticated, since while I call that a trampoline, you'd probably call it a boring loop that calls into a function.&lt;/p&gt;

&lt;p&gt;Here's the full script so you can see it in context:&lt;/p&gt;
&lt;script src="https://gist.github.com/1402840.js?file=GetLocalNuget.ps1"&gt;&lt;/script&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8129074" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=sNOoGkNHcuw:Q2w5sQmLYTA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=sNOoGkNHcuw:Q2w5sQmLYTA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=sNOoGkNHcuw:Q2w5sQmLYTA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=sNOoGkNHcuw:Q2w5sQmLYTA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=sNOoGkNHcuw:Q2w5sQmLYTA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=sNOoGkNHcuw:Q2w5sQmLYTA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=sNOoGkNHcuw:Q2w5sQmLYTA:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/sNOoGkNHcuw" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/General+Software+Development/default.aspx">General Software Development</category><category domain="http://weblogs.asp.net/jgalloway/archive/tags/Powershell/default.aspx">Powershell</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/12/15/working-around-a-powershell-call-depth-disaster-with-trampolines.aspx</feedburner:origLink></item><item><title>NuGet PowerShell Downloader Update - Adding Failed Download Retries, Better Paging Support</title><link>http://feedproxy.google.com/~r/jongalloway/~3/SAiY4d6vb-c/nuget-powershell-downloader-update-adding-failed-download-retries-better-paging-support.aspx</link><pubDate>Wed, 14 Dec 2011 18:57:43 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8122373</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8122373</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/12/14/nuget-powershell-downloader-update-adding-failed-download-retries-better-paging-support.aspx#comments</comments><description>&lt;p&gt;I previously posted a &lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/02/02/downloading-a-local-nuget-repository-with-powershell.aspx"&gt;NuGet PowerShell downloader script&lt;/a&gt;, which is handy for downloading a local NuGet repository. There are several common uses:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It's used in corporate environments where network policies prevent developers from accessing NuGet.org &lt;/li&gt;    &lt;li&gt;It's useful in cases where development teams want to build a customized feed with specific packages &lt;/li&gt;    &lt;li&gt;It's a great backup for presentations involving NuGet, especially on overloaded conference wi-fi &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;em&gt;Note: Now, look, I'm happy if the first two help you out, but that's not what I wrote it for. I wrote this because I was tired of watching speakers at conferences have problems installing NuGet packages and complaining about the slow conference wi-fi. Of course it's slow, it's always slow (&lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/02/02/downloading-a-local-nuget-repository-with-powershell.aspx"&gt;it's not lupus, it's never lupus!&lt;/a&gt;). If you're doing a presentation that involves you installing a NuGet package, part of your prep needs to be verifying that you have the required packages on your machine.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/podwysocki/"&gt;Matthew Podwysocki&lt;/a&gt; recently told me he was getting a call depth overflow error with the script. We looked at it, and it turned out that the problem was that he was downloading significantly more packages than had been available when I first wrote the script. I'd originally tested against several hundred, but there are &lt;a href="http://stats.nuget.org"&gt;over 16,000 available now (3,900 unique)&lt;/a&gt;. I updated the script to fix that, and while I was at it I added in support for retry if a package download fails for some reason. I'll describe the retry mechanism here and save the paging bit for the next post, since that's a bit more in-depth.&lt;/p&gt;  &lt;h2&gt;Handling Download Retries in PowerShell&lt;/h2&gt;  &lt;p&gt;Sometimes, downloads fail for any number of reasons. When you're downloading hundreds of files, chances of a failed download go up a bit, and I'd gotten a few requests to handle that better. The dumb-but-working workaround was to just run the script again, since it only downloads packages you don't have locally, but that's not elegant - plus, you might not notice that some of them had failed.&lt;/p&gt;  &lt;p&gt;A slightly less dumb workaround is just to retry the download a few times, with a limit to prevent an infinite loop if the file just can't be downloaded (e.g. bad link or missing file). This is pretty easy to implement with a try-catch loop, like this:&lt;/p&gt;  &lt;pre class="brush: ps; auto-links: false;"&gt;[int]$trials = 0
do {
    try {
        $trials +=1
        $webClient.DownloadFile($url, $saveFileName)
        break
    } catch [System.Net.WebException] {
        write-host &amp;quot;Problem downloading $url `tTrial $trials `
                   `n`tException: &amp;quot; $_.Exception.Message
    }
}
while ($trials -lt 3)&lt;/pre&gt;

&lt;p&gt;The general idea:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Start a counter ($trials) &lt;/li&gt;

  &lt;li&gt;Increment the counter &lt;/li&gt;

  &lt;li&gt;Try to download the file &lt;/li&gt;

  &lt;li&gt;If the download succeeds, &lt;strong&gt;break out of the retry loop - we're done here&lt;/strong&gt; &lt;/li&gt;

  &lt;li&gt;If we got a WebException, write out a message &lt;/li&gt;

  &lt;li&gt;If the counter's less than 3, try again. Otherwise, give up. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I was conflicted on the exception handling, but decided that I really only want to retry if I know that the failure was due to a Web Exceptions. If there were an unanticipated DownloadHasSetTheBuildingOnFireException or a BotNetUnleashedSecurityException on the first try, I'd rather not blindly repeat it. Thoughts?&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h2&gt;PowerShell 1.0? Forget about that try/catch part.&lt;/h2&gt;

&lt;p&gt;Try/Catch requires PowerShell 2.0 or later. If you're on PowerShell 1.0, you've got three options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Just use a &lt;a href="http://technet.microsoft.com/en-us/library/dd347548.aspx"&gt;trap&lt;/a&gt; and don't do retries &lt;/li&gt;

  &lt;li&gt;Rewrite this to use &lt;a href="http://powershell.com/cs/blogs/tips/archive/2009/09/14/trap-and-try-catch.aspx"&gt;logic inside the trap block&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Use &lt;a href="http://cashfoley.com/CommentView,guid,c3f862ff-b496-437d-925f-25c5f90ad482.aspx"&gt;one of the clever solutions out there that simulates try/catch in PowerShell 1.0&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are on PowerShell 1.0, as is the hapless Matt Podwysocki, you can see what we came up with &lt;a href="https://gist.github.com/1406652"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Converted to a gist&lt;/h2&gt;

&lt;p&gt;After having made a couple updates to this script and listing it in more than one place, it became obvious that this is exactly what a gist if for. If you haven't seen them, a gist is a single snippet of code that's posted in Github. It can be embedded in a blog post, but more importantly other users can comment on it and fork it, and I can update it. I've updated the original post to reference this gist as well, so if people stumble across the older blog post they'll automatically get the latest, greatest version of this script.&lt;/p&gt;

&lt;h2&gt;Script and Usage Instructions&lt;/h2&gt;

&lt;p&gt;I wrote up a walkthrough on the original post; usage hasn't changed with this update.&lt;/p&gt;
&lt;script src="https://gist.github.com/1402840.js?file=GetLocalNuget.ps1"&gt;&lt;/script&gt;

&lt;p&gt;The paging part is interesting in its own right. We'll talk about that in the next post.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8122373" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=SAiY4d6vb-c:AmLMBB3g0bA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=SAiY4d6vb-c:AmLMBB3g0bA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=SAiY4d6vb-c:AmLMBB3g0bA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=SAiY4d6vb-c:AmLMBB3g0bA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=SAiY4d6vb-c:AmLMBB3g0bA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=SAiY4d6vb-c:AmLMBB3g0bA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=SAiY4d6vb-c:AmLMBB3g0bA:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/SAiY4d6vb-c" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/12/14/nuget-powershell-downloader-update-adding-failed-download-retries-better-paging-support.aspx</feedburner:origLink></item><item><title>A look back at the ASP.NET site through the years</title><link>http://feedproxy.google.com/~r/jongalloway/~3/cwKmS9AKTyk/a-look-back-at-the-asp-net-site-through-the-years.aspx</link><pubDate>Fri, 02 Dec 2011 17:29:23 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8086104</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8086104</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/12/02/a-look-back-at-the-asp-net-site-through-the-years.aspx#comments</comments><description>&lt;p&gt;While writing up the release post for the new ASP.NET website, I started thinking about the site's changed over the years, and that lead me on a brief excursion through the &lt;a href="http://wayback.archive.org/web/*/http://www.asp.net/"&gt;Wayback Machine history of the ASP.NET home page&lt;/a&gt;.&amp;#160; Here are some highlights:&lt;/p&gt;  &lt;p&gt;Prior to 2001, the site was owned by &lt;a href="http://web.archive.org/web/20000815210453/http://www.asp.net/"&gt;ASP Computer Products, who appear to have been marketing an External Pocket Print Server for Fast Ethernet&lt;/a&gt;. Sadly, I missed my opportunity to go see it at Comdex 2000.&lt;/p&gt;  &lt;p&gt;The first ASP.NET related page available is in &lt;a href="http://web.archive.org/web/200101191049/http://www.asp.net/"&gt;2001&lt;/a&gt;, and it's pretty much just a splash page.&lt;/p&gt;  &lt;p&gt;&lt;a title="ASP.NET site - original" href="http://www.flickr.com/photos/36836555@N00/6438947187/"&gt;&lt;img border="0" alt="ASP.NET site - original" src="http://farm8.static.flickr.com/7156/6438947187_8711734cf3_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;By &lt;a href="http://web.archive.org/web/20021127010824/http://www.asp.net/"&gt;2002&lt;/a&gt;, the site had daily articles, Forums, Tutorials, a Control Gallery, and was advertising Web Matrix - the first one, built to help develop ASP.NET Web Forms.&lt;/p&gt;  &lt;p&gt;&lt;a title="ASP.NET Site - 2002" href="http://www.flickr.com/photos/36836555@N00/6438947587/"&gt;&lt;img border="0" alt="ASP.NET Site - 2002" src="http://farm8.static.flickr.com/7160/6438947587_a6389bc87d_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://web.archive.org/web/20051126072418/http://www.asp.net/default.aspx?tabindex=0&amp;amp;tabid=1"&gt;2005&lt;/a&gt; saw some big changes in November, for the release of Visual Studio 2005 and ASP.NET 2.0. I fondly remember that release - it was huge! I drove from San Diego to San Francisco to attend an early adopter training week, then spent a good year trying to get my company to buy into updating some of our sites to ASP.NET 2.0.&lt;/p&gt;  &lt;p&gt;&lt;a title="ASP.NET site - 2005" href="http://www.flickr.com/photos/36836555@N00/6438947653/"&gt;&lt;img border="0" alt="ASP.NET site - 2005" src="http://farm8.static.flickr.com/7003/6438947653_a3348909ed_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In &lt;a href="http://web.archive.org/web/20070805003746/http://www.asp.net/default.aspx?tabindex=0&amp;amp;tabid=1"&gt;2007&lt;/a&gt;, there was an update which brought in the blue color as well as the rounded corners and gradients I was complaining about earlier. &lt;/p&gt;  &lt;p&gt;&lt;a title="ASP.NET site - 2007" href="http://www.flickr.com/photos/36836555@N00/6438947717/"&gt;&lt;img border="0" alt="ASP.NET site - 2007" src="http://farm8.static.flickr.com/7174/6438947717_3517e5b168_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After that, thing didn't change much until March &lt;a href="http://web.archive.org/web/20100324003047/http://www.asp.net/default.aspx?tabindex=0&amp;amp;tabid=1"&gt;2010&lt;/a&gt;, our previous release.&lt;/p&gt;  &lt;p&gt;&lt;a title="ASP.NET - Home - New" href="http://www.flickr.com/photos/36836555@N00/4423727087/"&gt;&lt;img border="0" alt="ASP.NET - Home - New" src="http://farm5.staticflickr.com/4019/4423727087_bb4862e4d7_o.png" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And of course, our newest release just went live today, December 1, 2011.&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-12-01 17h00_36" href="http://www.flickr.com/photos/36836555@N00/6439128179/"&gt;&lt;img border="0" alt="2011-12-01 17h00_36" src="http://farm8.static.flickr.com/7028/6439128179_617a85f1df_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8086104" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=cwKmS9AKTyk:amEkkYrmQCM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=cwKmS9AKTyk:amEkkYrmQCM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=cwKmS9AKTyk:amEkkYrmQCM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=cwKmS9AKTyk:amEkkYrmQCM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=cwKmS9AKTyk:amEkkYrmQCM:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=cwKmS9AKTyk:amEkkYrmQCM:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=cwKmS9AKTyk:amEkkYrmQCM:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/cwKmS9AKTyk" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/ASP.NET/default.aspx">ASP.NET</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/12/02/a-look-back-at-the-asp-net-site-through-the-years.aspx</feedburner:origLink></item><item><title>ASP.NET website redesign: Now with less Beta, more Live</title><link>http://feedproxy.google.com/~r/jongalloway/~3/n9qVca7LZ0c/asp-net-website-redesign-now-with-less-beta-more-live.aspx</link><pubDate>Fri, 02 Dec 2011 06:42:02 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8085168</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>7</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8085168</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/12/01/asp-net-website-redesign-now-with-less-beta-more-live.aspx#comments</comments><description>&lt;p&gt;Back in October, &lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/10/10/asp-net-website-redesign-beta-what-s-changed-why-and-how-you-can-make-it-better.aspx"&gt;I posted about the beta release of the ASP.NET website redesign&lt;/a&gt; at beta.asp.net. Since then, we've listened to a lot of great feedback, ruthlessly evaluated a huge catalog of content, and continued to reorganize things so you can more easily find useful content. That redesign just graduated from beta to live today.&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-12-01 17h00_36" href="http://www.flickr.com/photos/36836555@N00/6439128179/"&gt;&lt;img border="0" alt="2011-12-01 17h00_36" src="http://farm8.static.flickr.com/7028/6439128179_617a85f1df_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This redesign was focused on the following goals:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;A newer Information Architecture&lt;/b&gt; (IA) that scales with different types of content. Trying to get you somewhere &lt;em&gt;useful &lt;/em&gt;quickly. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Content organized into relevant topic areas&lt;/strong&gt; (Overview, Videos, Tutorials, etc.) to make information easier to find and to learn a technology. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Improved on boarding experience&lt;/strong&gt; – Developers new to ASP.NET should find it easier to get started and download what they need. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Important Samples and Tutorials&lt;/strong&gt; are positioned prominently in the structure of the site so that they are easier to find. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Textual Tutorials are as important as videos &lt;/strong&gt;- We've heard people want text tutorials more than videos, so we're finding balance between these two kind of content. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Improved Social Integration – &lt;/strong&gt;&lt;a href="http://beta.asp.net/community"&gt;Community info&lt;/a&gt;, pulling from Twitter, Facebook and blogs. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;A less cluttered user experience&lt;/strong&gt; to get you where you need to go in fewer clicks. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Open Source and Samples &lt;/strong&gt;- We're looking for new ways to showcase great open source projects and excellent &lt;a href="http://code.msdn.com"&gt;samples&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Scott Hanselman's&amp;#160; and I planned that his blog post would cover the site overview and I'd focus on some specific details, so about the new site&amp;#160; blog covers the overview of what we did, so &lt;a href="http://www.hanselman.com/blog/NewASPNETWebsiteLaunched.aspx"&gt;be sure to read Scott's post for the big picture&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: It's going to sound like I'm taking credit for actually doing all this work. I've been very busy, but there were a lot of people involved. There's a dedicated development team working on it, and the closest I got to code or production access at any time was when I updated content in the CMS admin interface (yes, still Umbraco, and I'm very happy with it).&lt;/em&gt;&lt;/p&gt;  &lt;h2&gt;Information Architecture focus&lt;/h2&gt;  &lt;p&gt;Back in the early 2000's (maybe as early as 2004?) someone pointed me at some online workshop materials from &lt;a href="http://adaptivepath.com/"&gt;Adaptive Path&lt;/a&gt; which explained the process restructuring a website's navigation so that it's focused on the user's needs rather than the business's content. This was a revelation to me, and incredibly helpful as I was a tech lead on a project which moved a 20,000 website (comprised of 20,000 classic ASP pages, each a separate file) to a home-grown CMS running on ASP.NET 1.1.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The point is that what's behind the curtain - the different business units involved, the work that went into producing some aging content a few years ago, the work (administrative and development) involved in changing the navigation structure - none of it matters to me when I'm trying to find information I care about. &lt;/strong&gt;When I was interviewing for this job two years ago, I had plenty of experience - and frustration - with the ASP.NET site. I actually suggested that if the site couldn't be significantly improved, it was time to get rid of it completely. They still hired me, so I've continued to approach the ASP.NET site in that way - it needs to be useful, or it's not worthwhile.&lt;/p&gt;  &lt;p&gt;The steps:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://weblogs.asp.net/jgalloway/archive/2010/03/11/the-new-asp-net-website.aspx"&gt;&lt;strong&gt;Get the site on a modern CMS&lt;/strong&gt;&lt;/a&gt; (&lt;a href="http://umbraco.com"&gt;Umbraco&lt;/a&gt;, powered by ASP.NET of course) which could allow us to begin efficiently moving and editing content.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Restructure the site navigation around user tasks&lt;/strong&gt; rather than how our content had been historically grouped.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We took the first step with a site update in May 2010, and began on the second step. We broke out separate content around different technology focus areas (Web Pages, Web Forms, MVC) and started putting content maps on the landing pages for each of those technology areas. Those evolving content maps began to define how the site should be structured.&lt;/p&gt;  &lt;p&gt;So, here's a look at &lt;strong&gt;how the actually useful content in a page on the ASP.NET site has evolved over the past year&lt;/strong&gt;, leading up to this new release&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: Phase 2 below is not the final state, so hang on a second.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/jongalloway/6437752617/sizes/l/in/photostream/"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" src="http://farm8.staticflickr.com/7172/6437752617_c36bce6e8d_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Start&lt;/strong&gt;: Seven links at the top, each of which took you to pages with lists of content, usually organized in a way that made them hard to navigate. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Phase 1&lt;/strong&gt;: Surfacing some top links across several categories, but if you click on a &amp;quot;more&amp;quot; link, you go to a huge list of stuff, often hard to navigate. Cluttered with a lot of thumbnails which don't really add any value. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Phase 2&lt;/strong&gt;: Content map added, which is kind of a wall of text, but at least lists out some of the top content by topic. &lt;!--EndFragment--&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The content map was kind of a band-aid - it tried to show the structure we wished the site had, but once you clicked through on any of &lt;strong&gt;the links the dream collapsed&lt;/strong&gt;, and there was no real way to navigate around through the pretend structure.&lt;/p&gt;  &lt;p&gt;We refined at that pretend structure while it was just content in a page, focusing it on subject matter in a context (e.g. Security in ASP.NET MVC, Performance and Caching in ASP.NET Web Forms). Then, with this new release, &lt;strong&gt;we've made that pretend content the real content structure&lt;/strong&gt;. &lt;/p&gt;  &lt;h3&gt;The Navigation Tab Structure&lt;/h3&gt;  &lt;p&gt;The information architecture starts with a common tab format across the three technology focus areas:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm8.staticflickr.com/7014/6437940455_788aaf7447_z.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;Within each of these sections, we've divided content by use:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Overview&lt;/strong&gt; - This provides the main content map, linking to content in other tabs if appropriate (e.g. if you're interested in MVC Security and there happens to be an MVC Security section in the video tab, we'll link you to it. This content map also links to top content on MSDN as appropriate. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Tutorials &lt;/strong&gt;- These are generally multi-part walkthroughs which will teach a subject step by step. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Videos &lt;/strong&gt;- We separated videos out for each technology area, because we consume video differently than we consume textual content. If I'm looking for reference information on a topic and am in skim mode, videos aren't relevant. If I have some time to sit back and watch as someone demonstrates something, I only want to see videos. So, we separated them out, but we linked to them from the overview where appropriate. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Samples &lt;/strong&gt;- This tab lists sample applications with working source code, so you can see things in context. The samples include content from both inside and outside of Microsoft as appropriate, so we include popular open source applications which we think are useful as samples. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Forum &lt;/strong&gt;- The ASP.NET forums have been a great way to discuss issues and get help for a long time, but they've been a bit buried. I'll confess I don't think about them as the resource they are until I stumble across them in search results. We've included a tab which shows the dedicated forum for each technology area. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Books &lt;/strong&gt;- The books section was kind of off on its own before, too. I updated our books list and broke it into chapters which I thought were useful. Since this is now quick to update, I can go in and add new books as the become available. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Open Source &lt;/strong&gt;- We listed some top open source resources in each technology area which will help you in building your applications. This isn't a listing of open source applications running on ASP.NET, it's libraries and tools which will help you as you build your applications. It's of course not complete and can't include every open source resource available, but Scott Hanselman made a best effort at listing open source resources we'd recommend to fellow developers. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Oh, and the structure isn't pretend anymore&lt;/h3&gt;  &lt;p&gt;The landing page for a technology focus is the Overview tab, and you can see that we've subdivided the content in these areas into Chapters. Here's that same MVC page with that change:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm8.staticflickr.com/7013/6437847045_b6fc637699_z.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;You can really see it as you click into the content, though. That structure follows you around through the site, visible in the breadcrumb and table of contents in the right rail (highlight added to the image to point it out).&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm8.staticflickr.com/7030/6437871113_d8eb95626f_z.jpg" /&gt;&lt;/p&gt;  &lt;h3&gt;Multi-Part Article Navigation&lt;/h3&gt;  &lt;p&gt;For most of the content, the chapter format worked just fine. For a page showing a video about a Web Pages Security topic, we'd show the Web Page TOC in the right rail with that part of the Security section highlighted. &lt;strong&gt;There was one place where we needed a third navigational level, though: multi-part articles.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Most of the multi-part articles are in the tutorials section, since tutorials are often broken into a series of pages. As you work through one of these tutorials, you'll find that your breadcrumb looks something like this: &lt;a href="http://www.asp.net/"&gt;Home&lt;/a&gt;/&lt;a href="http://www.asp.net/mvc"&gt;MVC&lt;/a&gt;/&lt;a href="http://www.asp.net/mvc/tutorials"&gt;Tutorials&lt;/a&gt;/&lt;a href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc"&gt;Chapter 4. Getting Started with EF using MVC&lt;/a&gt;/&lt;a href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application"&gt;Creating a More Complex Data Model for an ASP.NET MVC Application (4 of 10)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In this case we're in the MVC &lt;strong&gt;technology area&lt;/strong&gt;, in the Tutorials &lt;strong&gt;tab&lt;/strong&gt;, in the Chapter 4. Getting Started with EF using MVC section of the Tutorial &lt;strong&gt;table of contents&lt;/strong&gt;, and we're on the 4th &lt;strong&gt;page&lt;/strong&gt; of that tutorial.&lt;/p&gt;  &lt;p&gt;To make the context clear, we mark that kind of content as multi-part, which shows a different kind of navigation in the right rail:&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-12-01 13h38_16" href="http://www.flickr.com/photos/36836555@N00/6438281859/"&gt;&lt;img border="0" alt="2011-12-01 13h38_16" src="http://farm8.static.flickr.com/7026/6438281859_b59feb8865_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This shows that you're in a multi-part article, and clearly shows your context.&lt;/p&gt;  &lt;h2&gt;Content Review&lt;/h2&gt;  &lt;p&gt;The next step was mapping a lot of content to this new structure and adjusting the structure when we found gaps or additional good content to surface. The site dates back to 2002(!) and has hosted a ton of content during that time. Some of that &lt;strong&gt;old content&lt;/strong&gt; is irrelevant or obsolete, but &lt;strong&gt;some of it continues to be useful to developers who are maintaining sites running on previous versions&lt;/strong&gt;. Additionally, there was useful content which had become &lt;strong&gt;orphaned&lt;/strong&gt; - unreachable via the site navigation - as a result of previous redesigns. We had literally thousands of pages of content, some filled with long lists of content, to evaluate.&lt;/p&gt;  &lt;p&gt;My thought process was this:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Is this information &lt;strong&gt;useful&lt;/strong&gt;? If a developer were asking me for information about this subject &lt;strong&gt;today&lt;/strong&gt;, would I recommend this particular page / video / tutorial? If not, delete it. &lt;/li&gt;    &lt;li&gt;Where does it fit in our site structure? If it doesn't, does the site structure need to change? &lt;/li&gt;    &lt;li&gt;Is this information complete, or would I recommend more information? If there's some available - including on MSDN - should we reference it? &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I worked with Scott Hunter, Scott Hanselman, ASP.NET team PM's for each of the focus areas, and the excellent writers and editors on the Web Platform &amp;amp; Tools Content Team (who contribute to and curate content both on MSDN and ASP.NET) to evaluate literally &lt;strong&gt;thousands&lt;/strong&gt; of pages. We did this in two passes:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;We split up the lists and evaluated each of the individual pages, recommending cut or keep, and if we were to keep it, where it should go. &lt;/li&gt;    &lt;li&gt;After completing that step, we had a series of bug bashes, in which individuals walk through a content area and report everything they thought should be changed. This was iterative - bug bash / fix /repeat. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The site was open during this whole cycle, and we got a lot of good feedback via social networks, the &lt;a href="http://aspnet.uservoice.com/forums/136460-www-asp-net-website-"&gt;dedicated ASP.NET website UserVoice forum&lt;/a&gt;, and from MVP's and ASP.NET Insiders. There's a lot of content here, and it will always be a work in progress, but we think the combined effort has helped to surface a lot more useful content in a way that's easier to find. Please &lt;a href="http://www.asp.net/feedback"&gt;let us know how we're doing&lt;/a&gt; - this site's only useful if it's providing you the content you're looking for.&lt;/p&gt;  &lt;h2&gt;Cleaner Markup, Faster Page Loads&lt;/h2&gt;  &lt;p&gt;The site was already pretty highly optimized, but we paid attention to the site performance and were happy to see page load times improve across the board.&lt;/p&gt;  &lt;h3&gt;More Semantic Markup&lt;/h3&gt;  &lt;p&gt;The previous design had a lot of dated (quaint?) design elements, like rounded corners and gradients, which at the time required a lot of extraneous markup for support across a wide range of browsers. There was a lot of wrapper divs which were there only for styling - kind of ignoring the most important element in HTML: text!&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Side note: I find it funny that, now that modern standards natively support rounded corners and gradients, they're not cool anymore.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;You can see a big difference in the markup just by looking at beginning of the body tag through the end of the header items. Here's the old design:&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;body&amp;gt;
    &amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;/webmatrix/tutorials/15-caching-to-improve-the-performance-of-your-website?&amp;quot;
    id=&amp;quot;form1&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;aspNetHidden&amp;quot;&amp;gt;
        &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;__VIEWSTATE&amp;quot; id=&amp;quot;__VIEWSTATE&amp;quot; value=&amp;quot;/wEPDwUENTM4MQ9kFgJmD2QWAmYPZBYCZg9kFgJmD2QWAgIFEGRkFgICD&lt;br /&gt; &lt;br /&gt;Q9kFgJmD2QWAmYPZBYCZg8WAh4HVmlzaWJsZWdkZKrDY1NG1HjNDVKzlZSX2Dy7poMS&amp;quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id=&amp;quot;content_container&amp;quot; class=&amp;quot;content_container&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;header_container&amp;quot;&amp;gt;
            &amp;lt;div class=&amp;quot;header_top&amp;quot;&amp;gt;
                &amp;lt;div class=&amp;quot;header_top_right&amp;quot;&amp;gt;
                    &amp;amp;nbsp;&amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class=&amp;quot;header_content&amp;quot;&amp;gt;
                &amp;lt;div class=&amp;quot;header_content_right&amp;quot;&amp;gt;
                    &amp;lt;a href=&amp;quot;http://www.asp.net&amp;quot; title=&amp;quot;Home Page&amp;quot;&amp;gt;
                        &amp;lt;img class=&amp;quot;logo&amp;quot; style=&amp;quot;border-width: 0px;&amp;quot; alt=&amp;quot;&amp;quot; src=&amp;quot;http://i2.asp.net/common/header/logo.png?cdn_id=22&amp;quot;
                            title=&amp;quot;Microsoft ASP.NET&amp;quot; /&amp;gt;
                    &amp;lt;/a&amp;gt;
                    &amp;lt;div id=&amp;quot;WLSearchBoxDiv&amp;quot;&amp;gt;
                        &amp;lt;div id=&amp;quot;WLSearchBoxPlaceholder&amp;quot;&amp;gt;
                            &amp;lt;input class=&amp;quot;search_box&amp;quot; id=&amp;quot;WLSearchBoxInput&amp;quot; disabled=&amp;quot;disabled&amp;quot; name=&amp;quot;WLSearchBoxInput&amp;quot;
                                value=&amp;quot;Search&amp;quot; /&amp;gt;&amp;lt;input class=&amp;quot;search_button&amp;quot; id=&amp;quot;WLSearchBoxButton&amp;quot; type=&amp;quot;button&amp;quot;
                                    value=&amp;quot;&amp;quot; name=&amp;quot;WLSearchBoxButton&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div id=&amp;quot;mainnav&amp;quot;&amp;gt;
                        &amp;lt;ul class=&amp;quot;nav_main&amp;quot;&amp;gt;
                            &amp;lt;li class=&amp;quot;first&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;/home&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/get-started&amp;quot;&amp;gt;Get Started&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;
                                &amp;lt;a href=&amp;quot;/downloads&amp;quot;&amp;gt;Downloads&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/web-pages&amp;quot;&amp;gt;Web Pages&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;
                                    &amp;lt;a href=&amp;quot;/web-forms&amp;quot;&amp;gt;Web Forms&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/mvc&amp;quot;&amp;gt;MVC&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/community&amp;quot;&amp;gt;
                                        Community&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;http://forums.asp.net&amp;quot;&amp;gt;Forums&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Yes, that was a bit of VIEWSTATE in there... Also, entire page was full of wrapper divs which were there just for formatting, and if you accidentally messed them up when editing content (oops) the whole page got wacky.&lt;/p&gt;

&lt;p&gt;Here's the header markup for that same page with the redesign:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;body class=''&amp;gt;
    &amp;lt;div class='allcontent '&amp;gt;
        &amp;lt;div class=&amp;quot;header-wrap&amp;quot;&amp;gt;
            &amp;lt;div class=&amp;quot;header&amp;quot;&amp;gt;
                &amp;lt;a href=&amp;quot;/&amp;quot; class=&amp;quot;logo&amp;quot; title=&amp;quot;The Official Microsoft ASP.NET Site&amp;quot;&amp;gt;The Official Microsoft
                    ASP.NET Site&amp;lt;/a&amp;gt;&amp;lt;ul class=&amp;quot;nav-main&amp;quot;&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/get-started&amp;quot;&amp;gt;Get Started &amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/downloads&amp;quot;&amp;gt;Downloads &amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/web-pages&amp;quot; class=&amp;quot;selected&amp;quot;&amp;gt;Web Pages &amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/web-forms&amp;quot;&amp;gt;Web Forms &amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/mvc&amp;quot;&amp;gt;MVC &amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/community&amp;quot;&amp;gt;Community &amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                        &amp;lt;li class=&amp;quot;last-child&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;http://forums.asp.net&amp;quot;&amp;gt;Forums&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;/pre&gt;

&lt;p&gt;I see that three goals are achieved in unison here:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Cleaner design means less HTML, so the pages load and render faster &lt;/li&gt;

  &lt;li&gt;Less junk/formatting HTML means the content is easier to maintain &lt;/li&gt;

  &lt;li&gt;A focus on content over superfluous design elements usually mean that the content is easier to read, as well &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Better Performance, YSlow Improvements&lt;/h3&gt;

&lt;p&gt;Again, the focus on this redesign was really about information architecture and design refresh, but we did pay attention to site performance and best practices throughout because... well, it's the ASP.NET site and we care about this stuff. We want to be proud of this site, and we want you to be proud of it, too.&lt;/p&gt;

&lt;p&gt;Scott Hunter, Scott Hanselman, and I were on several calls with the development team every week, and we constantly badgered them about performance tweaks, practices, etc. We started with a B &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt; rating, which is actually pretty good as far as most sites are concerned.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-12-01 09h57_16" href="http://www.flickr.com/photos/36836555@N00/6438733527/"&gt;&lt;img border="0" alt="2011-12-01 09h57_16" src="http://farm8.static.flickr.com/7156/6438733527_8af9209a4c_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We ended up with an A, with a discussion about any recommendation we couldn't meet. The only mark against us in the page below is due to some local (non-CDN) images, which was a measured decision to allow content editors to edit them in the CMS. Check the YSlow marks across the site yourself - it's a fun exercise.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-12-01 09h58_56" href="http://www.flickr.com/photos/36836555@N00/6438734383/"&gt;&lt;img border="0" alt="2011-12-01 09h58_56" src="http://farm8.static.flickr.com/7144/6438734383_4a5554ccf4_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking at better performance and best practices ensured we were doing things like setting correct headers, using sprites effectively, minimizing and bundling resources, etc. Again, I did absolutely none of that development work, I just sent e-mails about it. ;-)&lt;/p&gt;

&lt;p&gt;We had a team doing weekly performance testing across the site and making recommendations on best practices and opportunities to improve. Here's one of the pretty graphs in one of them showing the page load time was significantly reduced site-wide, often cutting the load time by 50% or more.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-12-01 15h17_44" href="http://www.flickr.com/photos/36836555@N00/6438728307/"&gt;&lt;img border="0" alt="2011-12-01 15h17_44" src="http://farm8.static.flickr.com/7160/6438728307_7cd6f98d94_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;What's Next?&lt;/h2&gt;

&lt;p&gt;We're definitely not done. We put a lot of things on the post-launch list, many of which are now possible as CMS edits. I mentioned that we've been asking for feedback and using your input to tell us what's most important. Here are some of the things we're tracking:&lt;/p&gt;

&lt;h3&gt;HTML5 Video&lt;/h3&gt;

&lt;p&gt;It's highly requested, and it's important to us, too. I prototyped a Silverlight with HTML5 fallback video solution which is in the &amp;quot;works on my machine&amp;quot; state. I went back and forth on which to make primary and which to make fallback, but since it's leveraging standard HTML content fallback (no Javascript or server logic required) it's easy to switch.&lt;/p&gt;

&lt;p&gt;As written, this would continue to use the existing player (along with features like time based commenting and cross-browser full screen support), but if Silverlight's not installed or is disabled, the content's shown using native HTML5 video support. If that's not available, we'll show some sort of message that indicates you need Silverlight or a newer browser.&lt;/p&gt;

&lt;p&gt;We know this is important so that the content's available across as many devices as possible, and it's high on the list.&lt;/p&gt;

&lt;h3&gt;Better Mobile and Smaller Device Support&lt;/h3&gt;

&lt;p&gt;I've blogged recently about how ASP.NET MVC 4 will use CSS media queries and adaptive layout to work well on different sized browsers, and adding adaptive layout is in the works for the ASP.NET site, too.&lt;/p&gt;

&lt;h3&gt;Fewer / smaller ads&lt;/h3&gt;

&lt;p&gt;Yes. We hear you, and we're pushing for it. Keep voting for it, it means a lot more when you ask for it than when I do.&lt;/p&gt;

&lt;h3&gt;Bring back old content&lt;/h3&gt;

&lt;p&gt;Aha! We've done that! Done. Taking the rest of the week off.&lt;/p&gt;

&lt;h3&gt;Your Feedback, give it to us&lt;/h3&gt;

&lt;p&gt;While we do watch for blog comments, by far the most effective way to get us feedback is to &lt;a href="http://aspnet.uservoice.com/forums/136460-www-asp-net-website-"&gt;vote on our www.asp.net website feedback page&lt;/a&gt; on UserVoice. Let us know how we can continue to improve!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8085168" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=n9qVca7LZ0c:BoQi08mEqbI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=n9qVca7LZ0c:BoQi08mEqbI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=n9qVca7LZ0c:BoQi08mEqbI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=n9qVca7LZ0c:BoQi08mEqbI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=n9qVca7LZ0c:BoQi08mEqbI:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=n9qVca7LZ0c:BoQi08mEqbI:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=n9qVca7LZ0c:BoQi08mEqbI:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/n9qVca7LZ0c" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/12/01/asp-net-website-redesign-now-with-less-beta-more-live.aspx</feedburner:origLink></item><item><title>Leveraging Background Services and Agents in Windows Phone 7 (Mango)</title><link>http://feedproxy.google.com/~r/jongalloway/~3/zvMfLr5_FWg/leveraging-background-services-and-agents-in-windows-phone-7-mango.aspx</link><pubDate>Wed, 23 Nov 2011 18:06:36 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8071070</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8071070</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/11/23/leveraging-background-services-and-agents-in-windows-phone-7-mango.aspx#comments</comments><description>&lt;p&gt;Earlier this month at DevConnections, I gave a presentation on Background Services and Agents in Windows Phone 7. The next week, I got to join Jesse Liberty on his podcast interviewing Peter Torr, a Prinicpal Product Manager on the Windows Phone team who's written a lot of great content about this exact subject.&lt;/p&gt;  &lt;p&gt;Overall, I was very impressed. I've done some basic Windows Phone development in the past, but nothing that really cutting edge. I really liked the way Windows Phone balanced enabling features for developers with protecting the phone's resources.&lt;/p&gt;  &lt;h4&gt;Side note: why you, Jon?&lt;/h4&gt;  &lt;p&gt;If you follow my blog, you might wonder what I was doing speaking on Windows Phone, since I don't talk about it much here. If you don't care, skip right on by to the next section...&lt;/p&gt;  &lt;p&gt;I'd originally proposed this talk because I thought it looked fun. Later I passed it to Jesse Liberty since he works with Windows Phone all the time, but helped him write up the outline and sample code because I thought it looked like fun (and partly because I'd dumped the talk on him). Then when he found out the week before DevConnections that he'd be unable to attend, I requested to take the talk back, because it looked like fun. This stuff is just plain cool to work with, and I had a blast preparing and presenting on it.&lt;/p&gt;  &lt;p&gt;While I don't do a lot of Windows Phone development, I've spent some time pair programming with Jesse on The Full Stack project, which includes a Windows Phone client. One of my main takeaways from that project was that it's really easy to get started with Windows Phone development, especially if you've done some Silverlight development - and I've done a good amount of Silverlight development. There are a few new concepts to wrap your mind around, but I was amazed how easy it was to get up and running.&lt;/p&gt;  &lt;h2&gt;Background Services - Start with the right mindset&lt;/h2&gt;  &lt;p&gt;You want your Windows Phone applications to do useful work in the background, but you don't want the background processes to affect the end user's phone experience. By experience, I mean:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You don't want them to interrupt or slow down foreground tasks (especially talking on the phone) in any way, ever &lt;/li&gt;    &lt;li&gt;You don't want them to run down the battery &lt;/li&gt;    &lt;li&gt;You don't want them to run up expensive bandwidth charges or interfere with foreground network usage &lt;/li&gt;    &lt;li&gt;You don't want anyone to have to think about them at all &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Rather than hope developers will keep the user and the above values in mind and do the right thing, Windows Phone background services provide a great framework for you to work within, and they automatically make sure you're playing within the rules. I think they've struck a great balance here, but when you're developing background services in Windows Phone, you need to keep this always in mind.&amp;#160; Your background services are most definitely managed, and they &lt;em&gt;will&lt;/em&gt; play within the rules. It's important to have that straight from the beginning.&lt;/p&gt;  &lt;h2&gt;Overview of services&lt;/h2&gt;  &lt;p&gt;Windows Phone background services are easier to understand when you get the idea of how they all fit together. I mentally broke them down into three generic types, with some pre-built &amp;quot;specialist&amp;quot; agents to handle common background use cases.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: Some of this logical grouping is stuff I came up with on my own to make sense of all of the different options. It's not officially approved by anyone but me, but it's just a mental model to help you understand what's available. Technically, if you look at the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.scheduler.scheduledaction(v=VS.92).aspx"&gt;ScheduledAction class hierarchy&lt;/a&gt;, Resource Intensive tasks fall right next to Periodic Tasks, but for the sake of understanding what the different types of tasks and actions do, I think it's easier to ignore that for a bit.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-11-22 17h10_37" href="http://www.flickr.com/photos/36836555@N00/6386360787/"&gt;&lt;img border="0" alt="2011-11-22 17h10_37" src="http://farm7.static.flickr.com/6213/6386360787_e921000d19_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Color coding explanation: &lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;Purple are custom tasks&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Green are pre-built, specialized tasks&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;Blue are general types&lt;/em&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Scheduled or Resource Intensive?&lt;/h3&gt;  &lt;p&gt;Scheduled tasks are things that don't require many resources (e.g. CPU, network) and need to run on some kind of schedule. Resource intensive tasks do require resources, so they can't dictate when they'll run.&lt;/p&gt;  &lt;p&gt;The Windows Phone operating system keeps background tasks from abusing resources by making decisions based on how resource intensive they are. Processes that require a lot of resources can only run when conditions are met (e.g. while charging or when battery power is high), and processes that run periodically or on a schedule can't use a lot of resources.&lt;/p&gt;  &lt;p&gt;Whatever, you say. I'll do what I want when I want because I'm a rebel. But, no, it's not that kind of setup here in background task land. &lt;a href="http://www.imdb.com/title/tt0057115/"&gt;For stealing tools, cooler&lt;/a&gt;. If your task doesn't abide by the rules, it's terminated.&lt;/p&gt;  &lt;h2&gt;Resource Intensive Tasks&lt;/h2&gt;  &lt;p&gt;Resource Intensive agents run for a relatively long period of time when the phone meets a set of requirements relating to &lt;strong&gt;processor activity&lt;/strong&gt;, &lt;strong&gt;power source&lt;/strong&gt;, and &lt;strong&gt;network connection&lt;/strong&gt;. An example here would be performing a long-running computation, or uploading a lot of data to a service.&lt;/p&gt;  &lt;p&gt;Since by their nature these tasks are expected to use resources, they're only allowed to run when resources are plentiful, e.g.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;External power required&lt;/li&gt;    &lt;li&gt;Non-cellular connection required&lt;/li&gt;    &lt;li&gt;Minimum battery power: 90%&lt;/li&gt;    &lt;li&gt;Device screen locked&lt;/li&gt;    &lt;li&gt;No active phone call&lt;/li&gt;    &lt;li&gt;Can't run longer than 10 minutes&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Built-in Resource Intensive Tasks&lt;/h2&gt;  &lt;p&gt;There are two built-in resource intensive task specialists - Background Audio and Background File Transfer. Since their use-cases are more defined, some of the above requirements are relaxed.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: I've decided to lump background audio and background file transfer under Resource Intensive tasks because they make some logical sense there - they do suck up resources, and they aren't scheduled. That's my logical grouping, it's not anything official.&lt;/em&gt;&lt;/p&gt;  &lt;h3&gt;Background Audio&lt;/h3&gt;  &lt;p&gt;Background Audio lets you queue and play audio while your device isn't active or even running. I showed two examples during my talk - one which queued up a bunch of tracks which continue to play when you navigate away, and another example which plays a ticking clock in a &lt;a href="http://www.pomodorotechnique.com/"&gt;Pomodoro&lt;/a&gt; application to remind you that you're still &amp;quot;on the clock.&amp;quot;&lt;/p&gt;  &lt;p&gt;The architecture of Background Audio is fascinating. It takes a little bit to figure out who's doing what, but it's really well put together. First, meet the two main players:&lt;/p&gt;  &lt;h4&gt;Audio Player Agent&lt;/h4&gt;  &lt;p&gt;It's your job to create the Audio Player Agent. You can do that by adding a new project to your solution and selecting one of the two Windows Phone Audio Agent project types (Playback or Streaming).&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-11-22 21h45_25" href="http://www.flickr.com/photos/36836555@N00/6387463259/"&gt;&lt;img border="0" alt="2011-11-22 21h45_25" src="http://farm7.static.flickr.com/6050/6387463259_d21af0c6f0_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Of course, you can write the code by hand if you prefer, but there's little point. This project template adds the necessary references and drops a single class into your Audio Player Agent project - a class which extends the AudioPlayerAgent base class and handles two events:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;OnPlayStateChanged&lt;/em&gt; - this is where you put the logic for when a track ends or is ready to be played&lt;/p&gt;  &lt;p&gt;&lt;em&gt;OnUserAction&lt;/em&gt; - this is where you respond to user input - things like play / pause / skip next / skip previous commands&lt;/p&gt;  &lt;p&gt;The important thing to get here is that &lt;strong&gt;your Audio Player Agent class is completely responsive&lt;/strong&gt;. Its only purpose is to respond to events.&lt;/p&gt;  &lt;h3&gt;Background Audio Player&lt;/h3&gt;  &lt;p&gt;There's only one Background Audio Player, and you don't own it. It belongs to the operating system, and you talk to it through its static BackgroundAudioPlayer.Instance property. Your application issues commands (requests?) to the Background Audio Player instance, which raises events in your Audio Player Agent.&lt;/p&gt;  &lt;p&gt;So your application code talks to the Background Audio Player Instance, which talks to your Audio Player Agent - your application code never talks to the Audio Player Agent. This makes sense when you remember that your application may be tombstoned or closed immediately after talking to the Background Audio Player, which doesn't matter - the Background Audio Player calls into your agent without having to spin up your application. Here's the diagram from MSDN that shows this communication:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://i.msdn.microsoft.com/dynimg/IC531096.png" /&gt;&lt;/p&gt;  &lt;p&gt;Note that the diagram shows the Background Audio Player is using two other operating system level components to play the music - the Zune Media Queue and the Universal Volume Control. This ends up giving a great experience to the end user with little work on your part: you queue up the audio, and the user can control the volume through a standard interface.&lt;/p&gt;  &lt;p&gt;See the &lt;a href="http://msdn.microsoft.com/en-us/library/hh394039(v=VS.92).aspx"&gt;Background Audio Overview on MSDN&lt;/a&gt; for more information on how these parts work together.&lt;/p&gt;  &lt;h3&gt;Background Audio Tips&lt;/h3&gt;  &lt;p&gt;Here are a few good things to keep in mind when developing background audio applications.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;For development, you can use F9 (volume down), F10 (volume up), and F11 (play/pause). &lt;/li&gt;    &lt;li&gt;Your background audio can be either an internet URL or a file in Isolated Storage. If you have audio you need to move to Isolated Storage, see &lt;a href="http://jesseliberty.com/2011/10/27/background-audio-part-ii-copying-audio-files-to-isolated-storage/"&gt;Jesse's post on how to do that&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Extra Credit: Background Audio Agent registration&lt;/h3&gt;  &lt;p&gt;Just because I'm one of those people who can't take &amp;quot;just because&amp;quot; for answer, I needed to know how the Background Audio Player knew how to find my application's Audio Player Agent. It turns out that's set up in your main application's WMAppManifest.xml (in the Properties folder). If you take a look at that, you'll see a section in there that lists tasks:&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;Tasks&amp;gt;
  &amp;lt;DefaultTask Name=&amp;quot;_default&amp;quot; NavigationPage=&amp;quot;MainPage.xaml&amp;quot; /&amp;gt;
  &amp;lt;ExtendedTask Name=&amp;quot;BackgroundTask&amp;quot;&amp;gt;
    &amp;lt;BackgroundServiceAgent Specifier=&amp;quot;AudioPlayerAgent&amp;quot; 
                            Name=&amp;quot;AudioPlaybackAgent1&amp;quot; 
                            Source=&amp;quot;AudioPlaybackAgent1&amp;quot; 
                            Type=&amp;quot;AudioPlaybackAgent1.AudioPlayer&amp;quot; /&amp;gt;
  &amp;lt;/ExtendedTask&amp;gt;
&amp;lt;/Tasks&amp;gt;&lt;/pre&gt;

&lt;h3&gt;Background File Transfer&lt;/h3&gt;

&lt;p&gt;The Background File Transfer service lets you register files for upload or download, and it takes it from there. It waits until appropriate conditions are met - for example, it only transfers small files over cellular networks, waiting for wi-fi or wired connection to transfer larger files - and raises events which your application can handle if it's running. It's all very fire-and-forget.&lt;/p&gt;

&lt;p&gt;A few things to be aware of here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The service won't run until conditions are met. The operating system imposes some, and you can add additional restrictions. &lt;strong&gt;The important thing to realize here is that the conditions may never be met, so the file transfer will never happen.&lt;/strong&gt; If you've requested a large file download which exceeds the cellular limits, but you have a user who never uses a wi-fi connection, they'll never get the file. So the responsibility is on your application to handle those exceptions.&lt;/li&gt;

  &lt;li&gt;Mango has great support for HTTP, so you can make use of headers like If-Modified-Since and ETAGs to optimize transfers.&lt;/li&gt;

  &lt;li&gt;You get both progress and completion events, so your UI can display status to users if they'd be interested.&lt;/li&gt;

  &lt;li&gt;You don't need a separate agent here. You register a TransferRequest with the service and subscribe to the events, but you don't need a service because the transfer service doesn't need you to respond to anything if your application's shut down.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Custom Resource Intensive Tasks&lt;/h3&gt;

&lt;p&gt;If you need to do something resource intensive - other than audio or file transfers - you can create your own Scheduled Task Agent. You do that the same way we added the Audio Player Agent previously - there's a project type just for that. These agents just have one method: OnInvoke. That's where you do all your resource intensive what-have-you. As I mentioned earlier, there are a lot of &lt;a href="http://msdn.microsoft.com/en-us/library/hh202942(v=VS.92).aspx"&gt;constraints on Resource Intensive Tasks, summarized in MSDN&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My main takeaway is that you can do some neat things with these, but you need to account for two things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You don't know when - or if at all - your user's phone will run your task.&lt;/li&gt;

  &lt;li&gt;If your task misbehaves, it will be terminated. Just like that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's how you'd register you Resource Intensive Task:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: false;"&gt;resourceIntensiveTask = new ResourceIntensiveTask(resourceIntensiveTaskName);
resourceIntensiveTask.Description = &amp;quot;This demonstrates a resource-intensive task.&amp;quot;;
ScheduledActionService.Add(resourceIntensiveTask);&lt;/pre&gt;

&lt;h2&gt;Scheduled Tasks&lt;/h2&gt;

&lt;p&gt;As with Resource Intensive tasks, you have a few options with scheduling. If you just want to notify the user, you can take advantage of some built in notifications (alarms and reminders); if you need to do something else you can create a custom Periodic Task.&lt;/p&gt;

&lt;h3&gt;Notifications&lt;/h3&gt;

&lt;p&gt;You've got two types here: Alarms and Reminders. Both are scheduled for some time in the future with a few lines of code, and that's it as far as your app is concerned. There are a few minor differences between the two:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Alarms will always have a title that says &amp;quot;Alarm&amp;quot; while Reminders can have a custom title&lt;/li&gt;

  &lt;li&gt;Alarms can play a custom sound, while Reminders will always play the system reminder tone&lt;/li&gt;

  &lt;li&gt;Tapping on an Alarm will launch the app and take you to the initial page of the application, as if it were just being launched. Reminders can include a navigation URI to a page inside your phone application, and it can contain querystring information as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Registering an alarm or reminder is pretty much identical, with the only difference being in supported properties. Example:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: false;"&gt;Reminder r = new Reminder(&amp;quot;Break_Over&amp;quot;);
r.Title = &amp;quot;Back To Work&amp;quot;;
r.Content = &amp;quot;Break's Over!&amp;quot;;
r.BeginTime = DateTime.Now.AddSeconds(10);
r.NavigationUri = NavigationService.CurrentSource;
ScheduledActionService.Add(r);&lt;/pre&gt;

&lt;h3&gt;Periodic Tasks&lt;/h3&gt;

&lt;p&gt;Periodic Tasks aren't really scheduled in the way I first assumed. They can be set to run as often as 30 minutes, but that time may drift by as much as 10 minutes. They may not run every cycle, depending on how busy the operating system is. They'll be terminated if they run longer than 25 seconds, but may be terminated sooner if the operating system decides it needs to.&lt;/p&gt;

&lt;p&gt;The point is that the Periodic Task system isn't a scheduler. It's a way to do light, low resource work in the background - small internet communications, updating a tile, etc. They're great for keeping the users phone up to date with nice to have information, but you have to assume that the task may run less often than you'd hoped, or potentially not at all.&lt;/p&gt;

&lt;p&gt;Creating a periodic task is really easy - it's the same idea as creating a resource intensive task. You add a Scheduled Task Agent to your project, then register it with the Scheduled Action Service like this:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: false;"&gt;periodicTask = new PeriodicTask(periodicTaskName);
periodicTask.Description = &amp;quot;This demonstrates a periodic task.&amp;quot;;
ScheduledActionService.Add(periodicTask);&lt;/pre&gt;

&lt;h2&gt;A couple of tricks&lt;/h2&gt;

&lt;h3&gt;Removing tasks before adding them&lt;/h3&gt;

&lt;p&gt;There are a few tricks to be aware of. First, the Periodic and Resource Intensive Tasks are registered by name - a string. So the above code I showed for both of them is overly simplistic - it will fail if you try to schedule the same task twice. The proper pattern is to find and remove the task before adding it:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: false;"&gt;periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;
if (periodicTask != null)
{
  ScheduledActionService.Remove(periodicTaskName);
}

periodicTask = new PeriodicTask(periodicTaskName);
periodicTask.Description = &amp;quot;This demonstrates a periodic task.&amp;quot;;
ScheduledActionService.Add(periodicTask);&lt;/pre&gt;

&lt;h3&gt;Launch for testing&lt;/h3&gt;

&lt;p&gt;Many of these things would be tough to test in normal conditions. For example, a there's no way I want to wait around 30-40 minutes to see if my Periodic Task will run correctly. Fortunately, you can use LaunchForTest to schedule a task when you're in debug mode.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: false;"&gt;#if DEBUG_AGENT
  ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(60));
#endif&lt;/pre&gt;

&lt;h3&gt;Toast&lt;/h3&gt;

&lt;p&gt;If you're running background processes, you may need to alert your users when things happen - completed task, failed task, significant task progress, etc. You can do that using ShellToast.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: false;"&gt;ShellToast toast = new ShellToast();
toast.Title = &amp;quot;Have some toast&amp;quot;;
toast.Content = toastMessage;
toast.Show();&lt;/pre&gt;

&lt;h2&gt;Slides, Podcast, Code&lt;/h2&gt;

&lt;p&gt;Here are the slides for my presentation at DevConnections:&lt;/p&gt;

&lt;div style="width: 595px" id="__ss_10279780"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Windows phone background tasks and agents" href="http://www.slideshare.net/jongalloway/windows-phone-background-tasks-and-agents" target="_blank"&gt;Windows phone background tasks and agents&lt;/a&gt;&lt;/strong&gt; &lt;iframe height="497" marginheight="0" src="http://www.slideshare.net/slideshow/embed_code/10279780?rel=0" frameborder="0" width="595" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;p&gt;Here's the podcast with Jesse Liberty, Peter Torr, and me talking about background services and agents in Windows Phone:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://jesseliberty.com/wp-content/media/Show52.mp3"&gt;Yet Another Podcast #52 - Peter Torr on Windows Phone Multitasking&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code samples from my demos are available &lt;a href="https://github.com/jongalloway/Presentations/tree/master/2011/DevConnections%20-%20Las%20Vegas/Windows%20Phone%20-%20Background%20Tasks"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Jesse and Peter have both written about Windows Phone multitasking topics on their blogs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Peter Torr's &lt;a href="http://blogs.msdn.com/b/ptorr/archive/2011/07/11/background-agents-part-1-of-3.aspx"&gt;Background Agents series&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Jesse Liberty's &lt;a href="http://jesseliberty.com/Topics/multitasking/"&gt;Windows Phone Multitasking series&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8071070" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=zvMfLr5_FWg:JPaK1y6CcBQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=zvMfLr5_FWg:JPaK1y6CcBQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=zvMfLr5_FWg:JPaK1y6CcBQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=zvMfLr5_FWg:JPaK1y6CcBQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=zvMfLr5_FWg:JPaK1y6CcBQ:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=zvMfLr5_FWg:JPaK1y6CcBQ:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=zvMfLr5_FWg:JPaK1y6CcBQ:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/zvMfLr5_FWg" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/Windows+Phone/default.aspx">Windows Phone</category><enclosure url="http://jesseliberty.com/wp-content/media/Show52.mp3" length="34827447" type="audio/mpeg" /><media:content url="http://jesseliberty.com/wp-content/media/Show52.mp3" fileSize="34827447" type="audio/mpeg" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> Earlier this month at DevConnections, I gave a presentation on Background Services and Agents in Windows Phone 7. The next week, I got to join Jesse Liberty on his podcast interviewing Peter Torr, a Prinicpal Product Manager on the Windows Phone team who</itunes:subtitle><itunes:summary> Earlier this month at DevConnections, I gave a presentation on Background Services and Agents in Windows Phone 7. The next week, I got to join Jesse Liberty on his podcast interviewing Peter Torr, a Prinicpal Product Manager on the Windows Phone team who's written a lot of great content about this exact subject. Overall, I was very impressed. I've done some basic Windows Phone development in the past, but nothing that really cutting edge. I really liked the way Windows Phone balanced enabling features for developers with protecting the phone's resources. Side note: why you, Jon? If you follow my blog, you might wonder what I was doing speaking on Windows Phone, since I don't talk about it much here. If you don't care, skip right on by to the next section... I'd originally proposed this talk because I thought it looked fun. Later I passed it to Jesse Liberty since he works with Windows Phone all the time, but helped him write up the outline and sample code because I thought it looked like fun (and partly because I'd dumped the talk on him). Then when he found out the week before DevConnections that he'd be unable to attend, I requested to take the talk back, because it looked like fun. This stuff is just plain cool to work with, and I had a blast preparing and presenting on it. While I don't do a lot of Windows Phone development, I've spent some time pair programming with Jesse on The Full Stack project, which includes a Windows Phone client. One of my main takeaways from that project was that it's really easy to get started with Windows Phone development, especially if you've done some Silverlight development - and I've done a good amount of Silverlight development. There are a few new concepts to wrap your mind around, but I was amazed how easy it was to get up and running. Background Services - Start with the right mindset You want your Windows Phone applications to do useful work in the background, but you don't want the background processes to affect the end user's phone experience. By experience, I mean: You don't want them to interrupt or slow down foreground tasks (especially talking on the phone) in any way, ever You don't want them to run down the battery You don't want them to run up expensive bandwidth charges or interfere with foreground network usage You don't want anyone to have to think about them at all Rather than hope developers will keep the user and the above values in mind and do the right thing, Windows Phone background services provide a great framework for you to work within, and they automatically make sure you're playing within the rules. I think they've struck a great balance here, but when you're developing background services in Windows Phone, you need to keep this always in mind.&amp;#160; Your background services are most definitely managed, and they will play within the rules. It's important to have that straight from the beginning. Overview of services Windows Phone background services are easier to understand when you get the idea of how they all fit together. I mentally broke them down into three generic types, with some pre-built &amp;quot;specialist&amp;quot; agents to handle common background use cases. Note: Some of this logical grouping is stuff I came up with on my own to make sense of all of the different options. It's not officially approved by anyone but me, but it's just a mental model to help you understand what's available. Technically, if you look at the ScheduledAction class hierarchy, Resource Intensive tasks fall right next to Periodic Tasks, but for the sake of understanding what the different types of tasks and actions do, I think it's easier to ignore that for a bit. Color coding explanation: Purple are custom tasks Green are pre-built, specialized tasks Blue are general types Scheduled or Resource Intensive? Scheduled tasks are things that don't require many resources (e.g. CPU, network) and need to run on some kind of schedule. Resource intensive tasks do require resources, so they </itunes:summary><itunes:keywords>Windows Phone</itunes:keywords><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/11/23/leveraging-background-services-and-agents-in-windows-phone-7-mango.aspx</feedburner:origLink></item><item><title>15 Pragmatic JavaScript Tips for ASP.NET Developers</title><link>http://feedproxy.google.com/~r/jongalloway/~3/8IRKEsr4dfg/15-pragmatic-javascript-tips-for-asp-net-developers.aspx</link><pubDate>Mon, 14 Nov 2011 19:31:33 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8056022</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8056022</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/11/14/15-pragmatic-javascript-tips-for-asp-net-developers.aspx#comments</comments><description>&lt;h2&gt;Here are 15 pragmatic JavaScript tips for ASP.NET developers from my recent presentation at DevConnections 2011 (Las Vegas). &lt;/h2&gt;  &lt;p&gt;The goal here is pragmatic tips - things you can use right away. Three or four are specific to ASP.NET Web Forms, the rest are pretty cross-cutting and in some cases apply to any web development platform. These are pragmatic tips, not advanced JavaScript development or coding practices, although I did sneak in a bit of SignalR, Node.js, and CoffeeScript at the end. If you're looking for coding practices, I'd highly recommend Elijah Manor's MIX11 talk: &lt;a href="http://www.elijahmanor.com/2011/04/mix11-video-good-javascript-habits-for.html"&gt;Good JavaScript Habits for C# Developers&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://damianedwards.wordpress.com"&gt;Damian Edwards&lt;/a&gt; has given a similar talk several times over the past year and kindly shared his samples and advice - his talks are all available &lt;a href="http://damianedwards.wordpress.com/presentations/"&gt;here&lt;/a&gt;. His talks covered a lot of great information, and my updated talk also included some future / edge stuff, like RIA/JS, Visual Studio 11, ASP.NET 4.5, Node.js, and CoffeeScript. Since I was covering a ton of information in an hour, I opted to structure this talk as a series of 15ish tips, building from the simple and easy material to, well, stuff like SignalR and Node.js with WebMatrix and iisnode.&lt;/p&gt;  &lt;p&gt;Slides are here:&lt;/p&gt;  &lt;div style="width: 425px" id="__ss_10109209"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Pragmatic JavaScript (DevConnections 2011)" href="http://www.slideshare.net/jongalloway/pragmatic-javascript-devconnections-2011" target="_blank"&gt;Pragmatic JavaScript (DevConnections 2011)&lt;/a&gt;&lt;/strong&gt; &lt;iframe height="355" marginheight="0" src="http://www.slideshare.net/slideshow/embed_code/10109209" frameborder="0" width="425" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/div&gt;  &lt;p&gt;I set up a new repo for presentations (slides and code) on Github; &lt;a href="https://github.com/jongalloway/Presentations/tree/master/2011/DevConnections%20-%20Las%20Vegas/Pragmatic%20JavaScript"&gt;here's the sample code for my demos&lt;/a&gt;. My presentation wasn't filmed, but Damian's talks at MIX and TechEd were. Links to those videos are in the &lt;a href="http://damianedwards.wordpress.com/presentations/"&gt;presentation section of his blog&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Okay, enough talking, more tips. Here we go:&lt;/p&gt;  &lt;h3&gt;Tip 1: If you’re using Ajax Control Toolkit, get the newest releases&lt;/h3&gt;  &lt;p&gt;It's been a while since I used the Ajax Control Toolkit, but it's still apparently very popular (substantiated by a show of hands at the presentation). The tip here is that - if you're still using Ajax Control Toolkit - you should be aware that there are regular new releases, and that they're available via NuGet.&lt;/p&gt;  &lt;p&gt;Recent releases include several new controls, including Gravatar, Twitter, and a new HTML editor. The new releases also include top fixes from the issues list, and there's a real emphasis on quality - as shown by the automated browser testing with QUnit. You can read more about recent updates on &lt;a href="http://stephenwalther.com/blog/category/15.aspx"&gt;Ajax Control Toolkit from Stephen Walther&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;The overall guidance from the ASP.NET team is that they're recommending jQuery for client-side coding. That's where future focus, project templates, code samples, etc., will be. However, if you're using Ajax Control Toolkit, you should be on the latest releases. It's easy to do now, since &lt;a href="http://nuget.org/List/Packages/AjaxControlToolkit"&gt;Ajax Control Toolkit can be installed and updated via NuGet&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Tip 2: Get to know jQuery&lt;/h3&gt;  &lt;p&gt;Sure, no surprise there. All web developers should know about jQuery, and if you're not using it you should have a pretty good reason. Here are the top advantages I listed:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;DOM abstraction &lt;/li&gt;    &lt;li&gt;Selector engine (I explained selectors using this &lt;a href="http://www.woods.iki.fi/interactive-jquery-tester.html"&gt;Interactive jQuery Selector Tester page&lt;/a&gt;) &lt;/li&gt;    &lt;li&gt;Plugin ecosystem &lt;/li&gt;    &lt;li&gt;Leverage CDN’s (talked about how end users have to wait for your custom scripts to download, while jQuery is very likely cached by their browser) &lt;/li&gt;    &lt;li&gt;Included in Microsoft templates (showed that File / New Project will put jQuery in your application) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I pointed out that JavaScript is beautiful and elegant, but sometimes extremely tricky. We looked at &lt;a href="http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/"&gt;variable hoisting&lt;/a&gt; as an example. The point is that JavaScript can be a bit tricky, and writing your own libraries when jQuery does it better is an unnecessary code liability to take on.&lt;/p&gt;  &lt;h3&gt;Tip 3: Install and Update jQuery via NuGet&lt;/h3&gt;  &lt;p&gt;ASP.NET MVC 3 already includes jQuery as a NuGet package, so it's easy to upgrade when a new version comes out. I showed how to remove the jQuery scripts from an ASP.NET Web Forms application and add jQuery via NuGet to get that same upgrade experience. We looked at adding jQuery plugins via NuGet, too.&lt;/p&gt;  &lt;h3&gt;Tip 4: Know how to find and use jQuery plugins&lt;/h3&gt;  &lt;p&gt;I explained what plugins are used for, and showed three great ways to find and use jQuery plugins:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://nuget.org/List/Search?searchTerm=jquery"&gt;NuGet&lt;/a&gt; (again, so you get update / package management) &lt;/li&gt;    &lt;li&gt;&lt;a href="http://plugins.jquery.com"&gt;http://plugins.jquery.com&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jqueryui.com"&gt;jQueryUI&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I showed the jQuery theme support, and we hooked up a few jQuery UI datepickers to ASP.NET textboxes.&lt;/p&gt;  &lt;h3&gt;Tip 5: Use jQuery UI via Unobtrusive Wire-up&lt;/h3&gt;  &lt;p&gt;Damian's written a nice &lt;a href="http://nuget.org/List/Packages/unobtrusive.jquery.ui"&gt;jQuery plugin to wire up jQuery UI widgets via HTML5 data- attributes&lt;/a&gt;, and it works for standard HTML and ASP.NET Web Forms controls. Here's an example:&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;asp:TextBox runat='server' ID='startDate'
    data-ui-fn='datepicker' /&amp;gt;
&amp;lt;div class='status-box' data-ui-fn='draggable resizable'&amp;gt;
    I'm a Drag and Droppable, resizable content area.
&amp;lt;/div&amp;gt;&lt;/pre&gt;
Joe Stagner has a full walkthrough on this here: &lt;a href="http://www.misfitgeek.com/2011/05/unobtrusive-javascript-in-your-asp-net-pages/"&gt;Unobtrusive JavaScript in your ASP.NET pages &lt;/a&gt;

&lt;h3&gt;Tip 6: Write your own jQuery plugins&lt;/h3&gt;

&lt;p&gt;We walked through turning some of our jQuery code into a plugin, making use of the &lt;a href="http://jquerysnippets.codeplex.com/"&gt;jQuery Code Snippets for Visual Studio 2010&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Plugins offer some great benefits, even if you never plan to distribute your plugin:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Code encapsulation &lt;/li&gt;

  &lt;li&gt;Reuse throughout one site or a number of projects (I talked about an example where my team bundled common jQuery code into plugins, and we were later able to leverage them from content input via CMS users) &lt;/li&gt;

  &lt;li&gt;Standard, tested modularization system that's designed to work well with jQuery &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good way to get started with writing your own jQuery plugins is the &lt;a href="http://docs.jquery.com/Plugins/Authoring"&gt;Plugin Authoring Tutorial on the jQuery site&lt;/a&gt;. It's really well written, starting with simple cases and slowly introducing advanced topics and best practices.&lt;/p&gt;

&lt;h3&gt;Tip 7: Take advantage of Visual Studio’s JavaScript support&lt;/h3&gt;

&lt;p&gt;I showed off some of the JavaScript editing and Intellisense features that are included in Visual Studio 2010. A lot of people aren't aware that the Intellisense infers type and can handle dynamic variables, loops, etc. Neat stuff.&lt;/p&gt;

&lt;p&gt;See Scott Guthrie's post, &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/04/08/javascript-intellisense-improvements-with-vs-2010.aspx"&gt;JavaScript Intellisense Improvements with VS 2010&lt;/a&gt;, for a nice walkthrough.&lt;/p&gt;

&lt;h3&gt;Tip 8: Get ready for Visual Studio 11 JavaScript features&lt;/h3&gt;

&lt;p&gt;Okay, Visual Studio 2010 has some nice JavaScipt editing features, but &lt;a href="http://msdn.microsoft.com/en-us/vstudio/hh127353"&gt;Visual Studio 11 Developer Preview&lt;/a&gt; is a huge advance here. It's actually using the same engine that's used in the Internet Explorer Developer Tools, and Visual Studio 11 adds a lot of goodness like implicit references (configurable by editing a JavaScript file), brace matching, outlining, etc.&lt;/p&gt;

&lt;p&gt;More on those features here: &lt;a href="http://bit.ly/vs11javascript"&gt;http://bit.ly/vs11javascript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since Visual Studio 11 Developer Preview works side-by-side with Visual Studio 2010, you can start using those features today. Yes, it's pre-release, but I'll give it the Works On My Machine certification - I've been using Visual Studio 11 Developer Preview side-by-side with Visual Studio 2010 since //build and it's been working great. Visual Studio 11 Developer Preview starts up so quickly, I'm often using it in cases where I would have used Notepad++.&lt;/p&gt;

&lt;h3&gt;Tip 9: Use the Visual Studio 2010 JScript Editor Extensions&lt;/h3&gt;

&lt;p&gt;&lt;img style="display: inline; float: right" align="right" src="http://farm7.static.flickr.com/6108/6345190396_0bf914365d_o_d.png" /&gt;Ah, you say, Visual Studio 11 Developer Preview is neat, but that's not what I call pragmatic. It's not out yet!&lt;/p&gt;

&lt;p&gt;Fine, there are some great Visual Studio extensions which give you a lot of the great features in Visual Studio 11 in Visual Studio 2010. That's no accident, some (like the &lt;a href="http://visualstudiogallery.msdn.microsoft.com/a15c3ce9-f58f-42b7-8668-53f6cdc2cd83"&gt;Web Essentials extension&lt;/a&gt;) are written by the PM's who are driving the Visual Studio 11 features.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://visualstudiogallery.msdn.microsoft.com/872d27ee-38c7-4a97-98dc-0d8a431cc2ed/"&gt;Visual Studio JScript Editor Extension&lt;/a&gt; adds a lot of the Visual Studio 11 JavaScript editing goodies to Visual Studio 2010. Things like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Brace Matching &lt;/li&gt;

  &lt;li&gt;Outlining / Code Folding &lt;/li&gt;

  &lt;li&gt;Current Word Highlighting &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is this pragmatic? Sure! It's a free, quick install, and if you do any JavaScript editing in Visual Studio it will pay for itself in no time!&lt;/p&gt;

&lt;h3&gt;Tip 10: Use ASP.NET 4 ScriptManager features&lt;/h3&gt;

&lt;p&gt;Okay, if you're using ASP.NET 4.0 Web Forms, you need to know about the new features in ScriptManager. In my talk I demo'd how easy it is to use CDN's and how to register scripts like a &lt;strike&gt;Ninja&lt;/strike&gt; &lt;strike&gt;Pirate&lt;/strike&gt; Honey Badger with &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.scriptresourcemapping.aspx"&gt;ScriptManager.ScriptResourceMapping&lt;/a&gt;. Script Resource Mappings offer a number of benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can register a library like jQuery by a version independent name (&amp;quot;jQuery&amp;quot;), so upgrading jQuery versions means that you only need to update the mapping in one place, rather than throughout your code &lt;/li&gt;

  &lt;li&gt;Using Script Resource Mappings really helps in cases where you may be referencing a library multiple times (e.g. in a page and in a multi-instance user controls within that page) since it will only include the script once &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pragmatic? Yes! This shipped with ASP.NET 4.0 (April 2010), and taking advantage of resource mappings and automatic CDN usage means you'll have more maintainable, higher performing, better script references with minimal effort.&lt;/p&gt;

&lt;h3&gt;Tip 12: Use RIA/JS for WCF services&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://wcf.codeplex.com/wikipage?title=RIA/JS"&gt;RIA/JS is a set of jQuery plugins&lt;/a&gt; for accessing RIA Services DomainService and OData services. My demo - for this (which was unfortunately pretty rushed) covered the BigShelf sample from the RIA/JS team, which shows how you can use WCF RIA Services to access WCF services from a browser using a really efficient JavaScript library. It includes full featured services, and your service calls are all using really light-weight JSON.&lt;/p&gt;

&lt;p&gt;The best way to get up to speed on what's new - and coming - in &lt;a href="http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-800T"&gt;WCF RIA Services is to watch Dinesh's talk at BUILD&lt;/a&gt;. Jeff Handley posted a good summary of the updates for //build which explains what's been released and what's in the works. The short summary is that if you're calling into WCF services from the browser, you should strongly consider using RIA/JS (Mea culpa).&lt;/p&gt;

&lt;h3&gt;Tip 13: Use SignalR for long-polling&lt;/h3&gt;

&lt;p&gt;Yeah, this is tons of fun. SignalR is a &amp;quot;smart&amp;quot; way to do long-polling with ASP.NET. For an example, I ran the StackExchange chat application and showed that each request was polling - sending a bunch of repetitive requests to the server, asking &amp;quot;Anything new? How about now? Now? Anything? Hey, anything new?&amp;quot;&lt;/p&gt;

&lt;p&gt;&lt;a title="HTTP Short Polling" href="http://www.flickr.com/photos/36836555@N00/6335257044/"&gt;&lt;img border="0" alt="HTTP Short Polling" src="http://farm7.static.flickr.com/6056/6335257044_bd8c656edc_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SignalR is a nice system (both client and server libraries available) which implements long polling, in which the browser makes a request and the server waits to respond (keeping the connection) open until there is new information to send to the client.&lt;/p&gt;

&lt;p&gt;&lt;a title="HTTP Long Polling with SignalR" href="http://www.flickr.com/photos/36836555@N00/6335257062/"&gt;&lt;img border="0" alt="HTTP Long Polling with SignalR" src="http://farm7.static.flickr.com/6216/6335257062_fb9073ba85_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You could &lt;a href="http://stackoverflow.com/questions/7788842/ajax-comet-is-there-any-solution-microsoft-is-working-on-or-supports-to-allow"&gt;implement this pattern on your own&lt;/a&gt; if you worked at it, but there's a good chance you'd be tying up threads on the server for each open request. Some smart guys on the ASP.NET team have set up this library to leverage stuff like the task parallel library, websocket support (if the browser supports it), takes advantage of async / await, etc.&lt;/p&gt;

&lt;p&gt;Is this pragmatic JavaScript? Absolutely! This is real, working code, you can &lt;a href="http://nuget.org/List/Packages/SignalR"&gt;install SignalR immediately via NuGet&lt;/a&gt;, and it improves scenarios in which the client is waiting for updates from the server because it's more performant and will return information to your clients immediately, rather than waiting for the next time they poll. The &lt;a href="https://github.com/SignalR/SignalR"&gt;source includes some great samples&lt;/a&gt;, including some multi-user applications like chat and a collaborative shape / drawing example.&lt;/p&gt;

&lt;p&gt;You can find out more in Scott Hanselman's recent post, &lt;a href="http://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspx"&gt;Asynchronous scalable web applications with real-time persistent long-running connections with SignalR&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Tip 14: Server-side JavaScript with iisnode and Node.js&lt;/h3&gt;

&lt;p&gt;Node.js is a popular system for writing server-side code in JavaScript, and it's optimized for high performance and asynchrony. I wrote a big post on it recently: &lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/10/26/using-node-js-in-an-asp-net-mvc-application-with-iisnode.aspx"&gt;Using Node.js in an ASP.NET MVC application with iisnode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Is this pragmatic? Well, this one is stretching things a bit, but I couldn't help myself. You can use Node.js in IIS using iisnode (even integrating it into an ASP.NET site, since iisnode runs as a standard IIS handler), and it works today. The Node.js community is big, and there are a ton of great packages available now. Is it likely people will start integrating Node.js into their ASP.NET Web Forms applications any time soon? Hard to say. One advantage is that you can reuse JavaScript code on client and server, which could be a big advantage if done right.&lt;/p&gt;

&lt;h3&gt;Tip 15: Adventurous? Keep an eye on CoffeeScript&lt;/h3&gt;

&lt;p&gt;Early on, I talked about the fact that JavaScript is powerful, but can be a bit tricky. Some of this is due to the fact that JavaScript is a dynamic, prototype based, weakly typed language masquerading under Java syntax. &lt;a href="http://coffeescript.org"&gt;CoffeeScript is a &amp;quot;little language&amp;quot; that compiles into JavaScript&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Underneath all those awkward braces and semicolons, JavaScript has always had a gorgeous object model at its heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One benefit of CoffeeScript is that it automatically prevents you from accidentally shooting yourself in the foot due to strange language quirks. If you're writing a lot of JavaScript, CoffeeScript is definitely worth a look. I recently wrote &lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/07/05/an-introduction-to-coffeescript.aspx"&gt;An introduction to CoffeeScript&lt;/a&gt; which explains how it works and how to get started.&lt;/p&gt;

&lt;h3&gt;What about you?&lt;/h3&gt;

&lt;p&gt;Okay, that's my list. Got any tips you'd like to share?&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8056022" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=8IRKEsr4dfg:Pvx4ibdGhdc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=8IRKEsr4dfg:Pvx4ibdGhdc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=8IRKEsr4dfg:Pvx4ibdGhdc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=8IRKEsr4dfg:Pvx4ibdGhdc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=8IRKEsr4dfg:Pvx4ibdGhdc:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=8IRKEsr4dfg:Pvx4ibdGhdc:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=8IRKEsr4dfg:Pvx4ibdGhdc:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/8IRKEsr4dfg" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/11/14/15-pragmatic-javascript-tips-for-asp-net-developers.aspx</feedburner:origLink></item><item><title>Using Node.js in an ASP.NET MVC application with iisnode</title><link>http://feedproxy.google.com/~r/jongalloway/~3/2IwxKMiUZxw/using-node-js-in-an-asp-net-mvc-application-with-iisnode.aspx</link><pubDate>Wed, 26 Oct 2011 18:17:59 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8013234</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>16</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=8013234</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/10/26/using-node-js-in-an-asp-net-mvc-application-with-iisnode.aspx#comments</comments><description>&lt;p&gt;&lt;img style="display: inline; float: right" align="right" src="http://nodejs.org/logos/nodejs-dark.png" /&gt;Node.js is an event-driven I/O server-side JavaScript environment based on the open-source V8 Javascript engine. It's really easy to run it on Windows now, and if you run it under iisnode, it's actually running under a standard IIS Handler, which means you can integrate it directly into ASP.NET applications.&lt;/p&gt;  &lt;p&gt;Node event-driven model is really interesting. There's been a lot of discussion on it lately; it's neither &lt;a href="http://teddziuba.com/2011/10/node-js-is-cancer.html"&gt;a cancer&lt;/a&gt; nor the &lt;a href="http://blog.brianbeck.com/post/node-js-cures-cancer"&gt;cure for cancer&lt;/a&gt;, but it makes it &lt;a href="http://al3x.net/2010/07/27/node.html"&gt;easier to handle scaling in the small&lt;/a&gt;. While you can handle asynchrony in most web frameworks, it's a fundamental part of Node. There's plenty of information out there on what Node is and how it's used, so I'm going to skip over that and reference a few good introductory posts:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://radar.oreilly.com/2011/07/what-is-node.html"&gt;What is Node.js?&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://code.danyork.com/2011/01/25/node-js-doctors-offices-and-fast-food-restaurants-understanding-event-driven-programming/"&gt;Node.js, Doctor’s Offices and Fast Food Restaurants – Understanding Event-driven Programming&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.hanselman.com/blog/InstallingAndRunningNodejsApplicationsWithinIISOnWindowsAreYouMad.aspx"&gt;Installing and Running node.js applications within IIS on Windows - Are you mad?&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Some background: Herding Code podcasts, early experiments&lt;/h2&gt;  &lt;p&gt;While Node has been mentioned enough on the Herding Code podcast enough that listeners have told it's been incorporated into the (unofficial) Herding Code drinking game, we've only had two official shows dedicated to Node so far. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://herdingcode.com/?p=299"&gt;Our first Node show (Herding Code 102, Jan 2011) was with Tim Caswell&lt;/a&gt;, who runs the &lt;a href="http://howtonode.org/"&gt;How To Node&lt;/a&gt; community blog site. I really appreciated Tim's overview, spanning from the basics of Node up through some more advanced uses. If you'd like an introduction to Node, I'd recommend listening to our interview with Tim - the portion of the show where he explained why Node is useful was clear enough that it got picked up by Read Write Web in a post titled &lt;a href="http://www.readwriteweb.com/hack/2011/01/wait-whats-nodejs-good-for-aga.php"&gt;Wait, What's Node Good for Again?&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Listen: &lt;a href="http://herdingcode.com/wp-content/uploads/HerdingCode-0102-Tim-Caswell-on-Node-js.mp3"&gt;Herding Code 102: Tim Caswell on Node.js&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In preparation for that interview, I followed some of Tim's tutorials and wrote my first Node code. In order to do that, I spun up an Ubuntu VM, because until recently Node didn't run very well on Windows. Since then I'd poked at it from time to time, but since it didn't really fit with my day-to-day development stack it was mostly an academic exercise.&lt;/p&gt;  &lt;h2&gt;The Windows port and libuv&lt;/h2&gt;  &lt;p&gt;That started to change this past June, when &lt;a href="http://blog.nodejs.org/2011/06/23/porting-node-to-windows-with-microsoft%E2%80%99s-help/"&gt;Ryan Dahl announced that Microsoft was partnering with Joyent to port Node to run natively on Windows&lt;/a&gt;. In Ryan's post, he mentioned that Bert Belder would be one of the developers working on that port, and earlier this month I posted &lt;a href="http://herdingcode.com/?p=347"&gt;our second Node show interviewing Bert&lt;/a&gt;. Bert talked about a lot of behind-the-scenes details about the port including:&lt;/p&gt;  &lt;h3&gt;libuv&lt;/h3&gt;  &lt;p&gt;Node previously ran on top of lib&lt;strong&gt;e&lt;/strong&gt;v, which is Unix-only. That's now changed to use the new &lt;a href="http://blog.nodejs.org/2011/09/23/libuv-status-report/"&gt;libuv platform library&lt;/a&gt;. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;code&gt;libuv&lt;/code&gt;‘s purpose is to abstract platform-dependent code in Node into one place where it can be tested for correctness and performance before bindings to V8 are added. Since Node is totally non-blocking, &lt;code&gt;libuv&lt;/code&gt; turns out to be a rather useful library itself: a BSD-licensed, minimal, high-performance, cross-platform networking library.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It's nice to see that this is paying off already - from the number of cross-platform applications listed in Ryan's post to examples like this &lt;a href="http://msdn.microsoft.com/en-us/library/hh527737(v=VS.103).aspx"&gt;Leveraging Node’ libuv in Windows Azure&lt;/a&gt; example on MSDN. &lt;/p&gt;  &lt;h3&gt;I/O Completion Ports&lt;/h3&gt;  &lt;p&gt;Windows included support for simultaneous, asynchronous I/O with &lt;a href="http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx"&gt;Input / Output Completion Ports&lt;/a&gt; (IOCP) way back in Windows NT 3.5 (circa 1994), so part of the work in getting Node running on Windows required adding IOCP support to libuv.&lt;/p&gt;  &lt;h3&gt;Cygwin&lt;/h3&gt;  &lt;p&gt;There was a previous version of Node that ran on Cygwin, for certain values of &amp;quot;ran.&amp;quot; I really appreciated Bert's response when asked whether they were able to use Cygwin in this port: it was exactly the opposite of what they were hoping to accomplish. Cygwin uses a compatibility layer to allow Unix applications run on Windows, which isn't ideal for performance. In contrast, this Node effort is focused on leveraging the native platform as much as possible.&lt;/p&gt;  &lt;p&gt;Listen: &lt;a href="http://herdingcode.com/wp-content/uploads/HerdingCode-0122-Bert-Belder-on-porting-nodejs-to-Windows.mp3"&gt;Herding Code 122: Bert Belder on porting node.js to Windows&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Running Node on Windows with iisnode&lt;/h2&gt;  &lt;p&gt;Node is just a single file executable. After installing Node, here's what my install folder looks like:&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-10-21 13h43_23" href="http://www.flickr.com/photos/36836555@N00/6267054969/"&gt;&lt;img border="0" alt="2011-10-21 13h43_23" src="http://farm7.static.flickr.com/6159/6267054969_1b081c0483_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The Node executable includes a server, so to have Node listen on a port you just call createServer and tell it what port to listen on:    &lt;br /&gt;&lt;/p&gt;  &lt;pre class="brush: js; auto-links: false;"&gt;var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337);
console.log('Server running at &lt;a href="http://127.0.0.1:1337/'"&gt;http://127.0.0.1:1337/'&lt;/a&gt;);&lt;/pre&gt;

&lt;p&gt;That's great for a simple case, but it's likely you'll want to have Node run under a host process, which handles things like auto-start, recovery, logging, etc. In the Unix world (from what I've read) this is often done using &lt;a href="http://howtonode.org/deploying-node-upstart-monit"&gt;monit and upstart&lt;/a&gt;, &lt;a href="http://stackoverflow.com/questions/5009324/node-js-nginx-and-now"&gt;fronted by nginx&lt;/a&gt;. In Windows, you can run Node under IIS using iisnode.&lt;/p&gt;

&lt;p&gt;Tomasz Janczuk (author of iisnode) summarizes &lt;a href="http://tomasz.janczuk.org/2011/08/hosting-nodejs-applications-in-iis-on.html"&gt;some of the benefits of hosting Node with iisnode&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Process management. &lt;/strong&gt;The iisnode module takes care of lifetime management of node.exe processes making it simple to improve overall reliability. You don’t have to implement infrastructure to start, stop, and monitor the processes. &lt;/em&gt;&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Scalability on multi-core servers&lt;/strong&gt;. Since node.exe is a single threaded process, it only scales to one CPU core. The iisnode module allows creation of multiple node.exe processes per application and load balances the HTTP traffic between them, therefore enabling full utilization of a server’s CPU capacity without requiring additional infrastructure code from an application developer. &lt;/em&gt;&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Auto-update&lt;/strong&gt;. The iisnode module ensures that whenever the node.js application is updated (i.e. the script file has changed), the node.exe processes are recycled. Ongoing requests are allowed to gracefully finish execution using the old version of the application, while all new requests are dispatched to the new version of the app. &lt;/em&gt;&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Access to logs over HTTP&lt;/strong&gt;. The iisnode module provides access the output of the node.exe process (e.g. generated by console.log calls) via HTTP. This facility is key in helping you debug node.js applications deployed to remote servers. &lt;/em&gt;&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Side by side with other content types&lt;/strong&gt;. The iisnode module integrates with IIS in a way that allows a single web site to contain a variety of content types. For example, a single site can contain a node.js application, static HTML and JavaScript files, PHP applications, and ASP.NET applications. This enables choosing the best tools for the job at hand as well progressive migration of existing applications. &lt;/em&gt;&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Minimal changes to node.js application code&lt;/strong&gt;. The iisnode module enables hosting of existing HTTP node.js applications with very minimal changes. Typically all that is required is to change the listed address of the HTTP server to one provided by the iisnode module via the process.env.PORT environment variable. &lt;/em&gt;&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;&lt;strong&gt;Integrated management experience&lt;/strong&gt;. The issnode module is fully integrated with IIS configuration system and uses the same tools and mechanism as other IIS components for configuration and maintenance.&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;WebMatrix templates for Node.js&lt;/h2&gt;

&lt;p&gt;While completely optional, there are also some handy WebMatrix templates which make it incredibly easy to kick the tires with Node running under iisnode. These templates are really small and simple, and don't do anything secret and magical (which is a good thing) other than give you some working code and a preconfigured web.config that maps the iisnode handler for you. Here's the contents of Empty Node project:&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-21 14h40_01" href="http://www.flickr.com/photos/36836555@N00/6267151201/"&gt;&lt;img border="0" alt="2011-10-21 14h40_01" src="http://farm7.static.flickr.com/6031/6267151201_0d06eb1724_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I said, this is a simple template to get you started, and I like that. There's a more involved Node.js Express template which includes some common modules like the Jade template engine, but the point I want to stress is that they're not fiddling with your registry or some secret config file or anything. They're a convenient way to quickly see some pre-configured Node.js code that Works On Your Machine(tm).&lt;/p&gt;

&lt;h2&gt;Installing iisnode and the Node.js WebMatrix templates&lt;/h2&gt;

&lt;p&gt;Scott Hanselman's done a couple of in-depth blog posts about getting started with Node on Windows using iisnode and some new WebMatrix templates:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.hanselman.com/blog/InstallingAndRunningNodejsApplicationsWithinIISOnWindowsAreYouMad.aspx"&gt;Installing and Running node.js applications within IIS on Windows - Are you mad?&lt;/a&gt; (nice intro to Node, explanation of why you'd use iisnode, and an install walkthrough) &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.hanselman.com/blog/WebMatrixAndNodejsTheEasiestWayToGetStartedWithNodeOnWindows.aspx"&gt;WebMatrix and node.js: The easiest way to get started with node on Windows&lt;/a&gt; (lists what you'd need to install and shows off the new Node templates) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd just like to get started quickly, I recommend walking through the second post. In my case, this took just a few minutes total (as I already had WebMatrix installed). &lt;a href="http://mysoftwarenotes.wordpress.com/2011/09/29/installing-nodejs-and-iisnode-on-windows/"&gt;Grahame Scott-Douglas typed up some great install notes&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href="http://www.microsoft.com/web/gallery/install.aspx?appid=webmatrix"&gt;&lt;em&gt;WebMatrix Install&lt;/em&gt;&lt;/a&gt;&lt;em&gt;: It took a looooong time to install, about 30 minutes. I was running quite a few things on my machine at the time, including VS2010 and SQL Mgmt Studio, but it still seemed like a heckuva long time, so be patient. &lt;/em&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a href="http://go.microsoft.com/?linkid=9784334"&gt;&lt;em&gt;node.js for Windows Install&lt;/em&gt;&lt;/a&gt;&lt;em&gt;: If you save to the default downloads folder in IE9 you’ll get the “This program is not commonly downloaded and could harm your computer” message. Click on “Actions” &amp;gt; “More actions” and “Run anyway”. Or you can open the folder in Windows explorer and double-click the file. Once you get that far the rest is easy. It installs to “C:\Program Files\nodejs” Add it to your path so you can play with the REPL and can run .js scripts. Once it’s in your path, just type “node” at the command prompt and there you have a JavaScript REPL! Or type “node myfile.js” and run JavaScript directly on Windows. Nice! &lt;/em&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a href="http://go.microsoft.com/?linkid=9784329"&gt;&lt;em&gt;iisnode for iis7 express (x86) Install&lt;/em&gt;&lt;/a&gt;&lt;em&gt;: If you don’t have &lt;/em&gt;&lt;a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=5555"&gt;&lt;em&gt;Microsoft Visual C++ 2010 Redistributable Package (x86)&lt;/em&gt;&lt;/a&gt;&lt;em&gt; installed then the iisnode installer will tell you that you need it. Just click my link here and get it. It installs easily and then the iisnode install is a piece of cake. (FYI: You’ll have the same “This program is not commonly … etc.” message if you try to run after downloading in IE9 and that’ll happen on the next two also.) &lt;/em&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a href="http://go.microsoft.com/?linkid=9784330"&gt;&lt;em&gt;iisnode for iis7 (x86) Install&lt;/em&gt;&lt;/a&gt;&lt;em&gt;: For my messing about I didn’t really need to install it but I wanted to anyway. There were no issues. &lt;/em&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a href="http://go.microsoft.com/?linkid=9784331"&gt;&lt;em&gt;iisnode for iis7 (x64) Install&lt;/em&gt;&lt;/a&gt;&lt;em&gt;: I didn’t install this, ’cause I’m using a 32 bit machine for this messing about, but if you are installing the x64 version then I’m guessing you’ll need the &lt;/em&gt;&lt;a href="http://www.microsoft.com/download/en/details.aspx?id=14632"&gt;&lt;em&gt;C++ 2010 redistributable for x64&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. &lt;/em&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a href="https://github.com/downloads/SteveSanderson/Node.js-Site-Templates-for-WebMatrix/Node.js%20Templates%20for%20WebMatrix.msi"&gt;&lt;em&gt;node.js templates for WebMatrix&lt;/em&gt;&lt;/a&gt;&lt;em&gt;: Easy install. Thanks to &lt;/em&gt;&lt;a href="http://blog.stevensanderson.com/"&gt;&lt;em&gt;Steve Sanderson&lt;/em&gt;&lt;/a&gt;&lt;em&gt; (the genius behind &lt;/em&gt;&lt;a href="http://knockoutjs.com/"&gt;&lt;em&gt;knockout.js&lt;/em&gt;&lt;/a&gt;&lt;em&gt;) for the templates.&lt;/em&gt; &lt;/li&gt;
  &lt;/ol&gt;
&lt;/ol&gt;

&lt;p&gt;With that complete, you can fire up WebMatrix and you'll see two new template options:&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-20 11h51_15" href="http://www.flickr.com/photos/36836555@N00/6267719552/"&gt;&lt;img border="0" alt="2011-10-20 11h51_15" src="http://farm7.static.flickr.com/6111/6267719552_86890e8f1e_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;What's in the Node.js Express Site template&lt;/h3&gt;

&lt;p&gt;The Node.js Express Site includes some useful modules:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://tjholowaychuk.com/post/664516126/connect-middleware-for-nodejs"&gt;connect&lt;/a&gt; - a middleware system for Node &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://expressjs.com/"&gt;express&lt;/a&gt; - a node web framework which provides things like routing, view infrastructure, content negotiation, etc. &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://tjholowaychuk.com/post/759178288/jade-haml-killer-for-nodejs"&gt;jade&lt;/a&gt; - a view template engine (conceptually similar to ASP.NET MVC view engines like Razor, but syntactically more similar to Haml) &lt;/li&gt;

  &lt;li&gt;&lt;a href="https://github.com/bentomas/node-mime"&gt;mime&lt;/a&gt; - a utility module for MIME-type lookups &lt;/li&gt;

  &lt;li&gt;qs - standard querystring parser &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: you can find more &lt;a href="https://github.com/joyent/node/wiki/modules"&gt;modules listed on the Node wiki&lt;/a&gt;, and there's a &lt;a href="http://stackoverflow.com/questions/6989273/some-connect-terminology"&gt;good discussion of how these pieces fit together on StackOverflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Express uses &lt;a href="http://www.sinatrarb.com/intro#Routes"&gt;Sinatra-style routing&lt;/a&gt;, so the controller-ish code is in routes.js:&lt;/p&gt;

&lt;pre class="brush: js; auto-links: false;"&gt;module.exports = function(app) {

    app.get('/', function (req, res) {
        res.render('index', { 
            message: 'Welcome to my site!' 
        });
    });
    
    app.get('/about', function (req, res) {
        res.render('about');
    });

}&lt;/pre&gt;

&lt;h3&gt;Views using the Jade template engine&lt;/h3&gt;

&lt;p&gt;You'll see that a request to the root of the site (matching the pattern &amp;quot;/&amp;quot;) will return the index view, passing it a JSON model containing a message that says &amp;quot;Welcome to my site!&amp;quot; Looking at the index template (/views/index.jade.txt), you'll see that Jade is extremely terse:&lt;/p&gt;

&lt;pre&gt;- locals.pageTitle = &amp;quot;Home page&amp;quot;

p= message&lt;/pre&gt;

&lt;p&gt;And that uses a layout (/views/layout.jade.txt) which is also pretty simple:&lt;/p&gt;

&lt;pre&gt;!!! html
html
    head
        if locals.pageTitle
            title= pageTitle
        link(href=&amp;quot;/css/site.css&amp;quot;, rel=&amp;quot;stylesheet&amp;quot;, type=&amp;quot;text/css&amp;quot;)
    body
        div.header
            h1 My Node.js Site
            nav
                a(href='/') Home
                a(href='/about') About
        != body&lt;/pre&gt;

&lt;p&gt;Hitting Run, you'll see that WebMatrix has spun up site in IIS Express and we've got a simple page.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-21 17h24_06" href="http://www.flickr.com/photos/36836555@N00/6267658893/"&gt;&lt;img border="0" alt="2011-10-21 17h24_06" src="http://farm7.static.flickr.com/6216/6267658893_a83f5ec8de_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Side note: I'm not going to go into detail, but &lt;a href="https://github.com/visionmedia/jade#readme"&gt;Jade's syntax&lt;/a&gt; is pretty neat. It brings in the semantic focus of &lt;a href="http://en.wikipedia.org/wiki/Haml"&gt;Haml&lt;/a&gt; (available in ASP.NET as NHaml), but with some nice improvements (e.g. there's no need to prefix tags with %), and it's cool to have one language (Javascript) for both server and client side code. Example:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;- locals.pageTitle = &amp;quot;Home page&amp;quot;

p= message

//Server-side logic in Javascript
- if (message.length)
  ul
    - each word in message.split(&amp;quot; &amp;quot;)
      li= word

//Client-side Javascript
script
    alert(&amp;quot;The message is: #{message}&amp;quot;)&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;pre&gt;&lt;font face="Segoe UI"&gt;&lt;/font&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;As shown in the comments, the first bit of script runs Javascript code on the server, and the second bit of script runs Javascript code on the client. That's awesome.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-21 19h16_58" href="http://www.flickr.com/photos/36836555@N00/6268183420/"&gt;&lt;img border="0" alt="2011-10-21 19h16_58" src="http://farm7.static.flickr.com/6106/6268183420_85caaa2668_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Back to that iisnode is an IIS Handler thing&lt;/h2&gt;

&lt;p&gt;Okay, so Node is of course interesting and useful on its own - the above sample shows an application with routing, a nice view engine, etc. If you want to handle the hosting yourself, knock yourself out. If you're using Windows, you've got IIS available, and iisnode can host the Node process for you.&lt;/p&gt;

&lt;p&gt;I really like new toys that play well with existing technologies, and one cool advantage of iisnode is that you can use it to integrate Node directly into an existing ASP.NET application. That all works because iisnode is an &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.aspx"&gt;HttpHandler&lt;/a&gt;, which has been supported in .NET since .NET 1.1. That means that you can seamlessly route ASP.NET requests to ASP.NET and Node requests to Node.exe (running under iisnode) &lt;a href="http://msdn.microsoft.com/en-us/library/bb398986.aspx"&gt;using the standard mechanisms the ASP.NET and IIS have supported for a very long time&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;A simple iisnode web.config example&lt;/h3&gt;

&lt;p&gt;If you look the web.config in the Node.js Express Site, you can see how the iisnode handler is configured:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;configuration&amp;gt;
    &amp;lt;system.webServer&amp;gt;

        &amp;lt;handlers&amp;gt;
            &amp;lt;!-- indicates that the app.js file is a node.js application to be handled by the iisnode module --&amp;gt;
            &amp;lt;add name=&amp;quot;iisnode&amp;quot; path=&amp;quot;app.js&amp;quot; verb=&amp;quot;*&amp;quot; modules=&amp;quot;iisnode&amp;quot; /&amp;gt;
        &amp;lt;/handlers&amp;gt;
    
	&amp;lt;!-- Rewrite rulex excerpted for brevity --&amp;gt; 
        
	&amp;lt;!-- You can control how Node is hosted within IIS using the following options --&amp;gt;
        &amp;lt;!--
        &amp;lt;iisnode      
            nodeProcessCommandLine=&amp;quot;%systemdrive%\node\node.exe&amp;quot;
            maxProcessCountPerApplication=&amp;quot;4&amp;quot;
            maxConcurrentRequestsPerProcess=&amp;quot;1024&amp;quot;
            maxPendingRequestsPerApplication=&amp;quot;1024&amp;quot;
            maxNamedPipeConnectionRetry=&amp;quot;3&amp;quot;
            namedPipeConnectionRetryDelay=&amp;quot;2000&amp;quot;      
            asyncCompletionThreadCount=&amp;quot;4&amp;quot;
            initialRequestBufferSize=&amp;quot;4096&amp;quot;
            maxRequestBufferSize=&amp;quot;65536&amp;quot;
            uncFileChangesPollingInterval=&amp;quot;5000&amp;quot;
            gracefulShutdownTimeout=&amp;quot;60000&amp;quot;
            loggingEnabled=&amp;quot;true&amp;quot;
            logDirectoryNameSuffix=&amp;quot;logs&amp;quot;
            maxLogFileSizeInKB=&amp;quot;128&amp;quot;
            appendToExistingLog=&amp;quot;false&amp;quot;
        /&amp;gt;
        --&amp;gt;
    
    &amp;lt;/system.webServer&amp;gt;
&amp;lt;/configuration&amp;gt;&lt;/pre&gt;

&lt;p&gt;Note that there's only one required setting, which enables the iisnode handler and points it at app.js. The sample template includes an example section (commented out) which shows additional configuration options. &lt;/p&gt;

&lt;h3&gt;Playing nicely with existing Javascript files&lt;/h3&gt;

&lt;p&gt;Since we don't want to interfere with our client-side .js files, we need to tell the handler how to distinguish between client-side and server-side .js files. &lt;a href="http://tomasz.janczuk.org/"&gt;Tomasz Janczuk&lt;/a&gt;, &lt;a href="https://github.com/tjanczuk/iisnode"&gt;developer of iisnode&lt;/a&gt;, has posted a lot &lt;a href="http://tomasz.janczuk.org/2011/08/hosting-nodejs-applications-in-iis-on.html"&gt;of information about how configuring iisnode using web.config&lt;/a&gt;, including a few ways to handle that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Point the handler at a specific file like the sample above, which tells iisnode only to handle requests for app.js &lt;/li&gt;

  &lt;li&gt;Use another file extension, like .njs, for server-side .js files. In that case, you'd use path=&amp;quot;*.njs&amp;quot; &lt;/li&gt;

  &lt;li&gt;Use a &amp;lt;location&amp;gt; element to specify that iisnode should handle all .js files in a specific directory &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: Remember that due to the web.config hierarchy and inheritance, so you can make system-wide settings that relate to iisnode, at the app level, etc.&lt;/p&gt;

&lt;h2&gt;Simple example: Including a Node endpoint in an existing ASP.NET MVC Application&lt;/h2&gt;

&lt;p&gt;With the above in mind, it's pretty simple include some Node goodness in an existing ASP.NET MVC application. Here's how:&lt;/p&gt;

&lt;h3&gt;Ensure the project is using the IIS Express server (rather than the ASP.NET Development Server, a.k.a. Cassini)&lt;/h3&gt;

&lt;p&gt;In order to take advantage of iisnode, you'll need to switch your project's server to IIS Express if you haven't already.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://learn.iis.net/page.aspx/868/iis-express-overview/"&gt;IIS Express is a lightweight, self-contained version of IIS optimized for developers&lt;/a&gt; - it's included with WebMatrix and Visual Studio 2010 SP1, or you can &lt;a href="http://www.microsoft.com/web/gallery/install.aspx?appid=IISExpress"&gt;install it individually using Web Platform Installer&lt;/a&gt;. It gives you most of the benefits of running in the full IIS environment, but runs as an application under user permissions rather than a full system-level server. We interviewed &lt;a href="http://herdingcode.com/?p=265"&gt;Vaidy Gopalakrishnan about IIS Express on Herding Code 89 if you'd like to know more&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Listen: &lt;a href="http://herdingcode.com/wp-content/uploads/HerdingCode-0089-Vaidy%20Gopalakrishnan-on-IIS-Developer-Express.mp3"&gt;Herding Code 89: Vaidy Gopalakrishnan on IIS Developer Express&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Node: You can (of course) develop your project against the full IIS server and take advantage of iisnode. In most cases, though iisnode is a better choice for development.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Switching your project to use IIS Express is incredibly simple: right-click the project and select &amp;quot;Use IIS Express...&amp;quot; then confirm the resulting dialog.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-25 16h22_12" href="http://www.flickr.com/photos/36836555@N00/6283648168/"&gt;&lt;img border="0" alt="2011-10-25 16h22_12" src="http://farm7.static.flickr.com/6116/6283648168_fb1a334e03_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Configure the iisnode handler in web.config&lt;/h3&gt;

&lt;p&gt;I listed a few options for incorporating node into an application above. In this case, I've decided to add a Node directory to the project and use the &amp;lt;location&amp;gt; element to target it. To do that, I included the following directly under the &amp;lt;configuration&amp;gt; node:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;location path=&amp;quot;Node&amp;quot;&amp;gt;
  &amp;lt;system.webServer&amp;gt;
    &amp;lt;handlers&amp;gt;
      &amp;lt;add name=&amp;quot;iisnode&amp;quot; path=&amp;quot;*.js&amp;quot; verb=&amp;quot;*&amp;quot; modules=&amp;quot;iisnode&amp;quot; /&amp;gt;
    &amp;lt;/handlers&amp;gt;
  &amp;lt;/system.webServer&amp;gt;
&amp;lt;/location&amp;gt;&lt;/pre&gt;

&lt;p&gt;Next, I added a Javascript file to that Node directory (right-click the folder, Add New Item, JScript File (yes, JScript is a silly name)). I played with some different, more complex examples, but in the end I decided to keep it simple and just return HTML (&lt;a href="http://www.imdb.com/character/ch0069595/quotes"&gt;with apologies to GLaDOS&lt;/a&gt;):&lt;/p&gt;

&lt;pre class="brush: js; auto-links: false;"&gt;var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.write('&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;link href=&amp;quot;/Content/Site.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; /&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;');
    res.write('&amp;lt;h1&amp;gt;Are you still there?&amp;lt;/h1&amp;gt;');
    res.write('&amp;lt;p&amp;gt;');
        res.write('We are pleased that you made it through the final challenge where we pretended we were going to murder you. We are very very happy for your success. ');
        res.write('We are throwing a party in honor of your tremendous success. Place the device on the ground, then lie on your stomach with your arms at your sides. ');
        res.write('A party associate will arrive shortly to collect you for your party. Make no further attempt to leave the testing area. ');
    res.write('&amp;lt;/p&amp;gt;');
    res.write('&amp;lt;p&amp;gt;');
        res.write(&amp;quot;Proceed to test chamber &amp;quot; + process.env.PORT);
    res.write('&amp;lt;/p&amp;gt;');
    res.end('&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;');
}).listen(process.env.PORT); &lt;/pre&gt;

&lt;p&gt;Note that near the end we return process.env.PORT, which will return the port that Node is listening on. Want to guess which one? You'll never guess...&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-26 10h13_41" href="http://www.flickr.com/photos/36836555@N00/6283251971/"&gt;&lt;img border="0" alt="2011-10-26 10h13_41" src="http://farm7.static.flickr.com/6120/6283251971_b93663c53f_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Did you guess it? Sorry, it was a trick question - iisnode is apparently communicating with Node over a named pipe rather than a port. Neat.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note 1: This is an incredibly simple example, and it doesn't show off what iisnode is really built for. Some more compelling, really world examples of integrating into an ASP.NET site might include running a backend service (socket I/O, chat, XMPP), providing a service to handle Ajax requests, or otherwise taking advantage of Node's asynchronous, evented model. If I were to do anything more complex, I'd want to take advantage of the rich &lt;/em&gt;&lt;a href="https://github.com/joyent/node/wiki/modules"&gt;&lt;em&gt;Node module ecosystem&lt;/em&gt;&lt;/a&gt;&lt;em&gt; rather than writing everything from scratch. I decided not to do that here because I want to focus on the getting started scenario. If time permits, I'd love to do a follow-up that's more advanced.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note 2: While this is mostly a completely standalone page that's oblivious to the surrounding ASP.NET MVC site, it doesn't need to stay that way. I did reference the site's stylesheet, and there's no reason I couldn't be calling into the database, any server-side services, etc.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Development Environment support and Logging&lt;/h3&gt;

&lt;p&gt;There's no server-side debugging support for Node in Visual Studio or WebMatrix (yet - here's hoping they add it). There are some development environments available that do have that, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://github.com/ajaxorg/cloud9"&gt;Cloud9 IDE&lt;/a&gt; (local version) &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.jetbrains.com/webstorm/"&gt;WebStorm&lt;/a&gt; with the &lt;a href="http://plugins.intellij.net/plugin/?idea&amp;amp;id=6098"&gt;NodeJS Plugin&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="https://github.com/dannycoates/node-inspector"&gt;node-inspector&lt;/a&gt; (&lt;a href="http://codebetter.com/glennblock/2011/10/13/using-node-inspector-to-debug-node-js-applications-including-on-windows-and-using-ryppi-for-modules/"&gt;great walkthrough on getting this set up by Glenn Block&lt;/a&gt;) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, IIS does provide failed request tracing and logging, both of which are helpful for simple debugging. I'll break the code in my index.js sample above by requiring a (missing) cake module on first line:&lt;/p&gt;

&lt;pre class="brush: js; auto-links: false;"&gt;var cake = require('cake');&lt;/pre&gt;

&lt;p&gt;When I run this, I'll see an HTTP 500 error message page from IIS which tells me where to find my failed request tracing logs. In this case, failed request tracing isn't going to give as much info as the logs, but let's take a look.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-26 10h45_53" href="http://www.flickr.com/photos/36836555@N00/6283350301/"&gt;&lt;img border="0" alt="2011-10-26 10h45_53" src="http://farm7.static.flickr.com/6237/6283350301_33342db4c1_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That directory contains a bunch of XML files with the request tracing logs. Opening the latest shows that I have a file not found error.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-26 10h56_13" href="http://www.flickr.com/photos/36836555@N00/6283366865/"&gt;&lt;img border="0" alt="2011-10-26 10h56_13" src="http://farm7.static.flickr.com/6220/6283366865_6aaa6e2cb7_b.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Failed request diagnostics are really helpful for a lot of more complex scenarios, but in this case I've got a simple code error, and the Node logs will be a lot more helpful. Logging was automatically enabled by iisnode - to disable or configure logging, see the commented-out &amp;lt;iisnode&amp;gt; element in the first web.config sample. The default location for the index.js logs is in a /Node/iisnode.js.logs directory. There's one log file in it - 0.txt - and it tells me what went wrong:&lt;/p&gt;

&lt;pre&gt;node.js:203
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: Cannot find module 'cake'
    at Function._resolveFilename (module.js:334:11)
    at Function._load (module.js:279:25)
    at Module.require (module.js:357:17)
    at require (module.js:368:17)
    at Object.&amp;lt;anonymous&amp;gt; (C:\Users\Jon\Documents\Jon-Share\Projects\NodeMusicStore\MvcMusicStore\MvcMusicStore\Node\index.js:1:74)
    at Module._compile (module.js:432:26)
    at Object..js (module.js:450:10)
    at Module.load (module.js:351:31)
    at Function._load (module.js:310:12)
    at Array.&amp;lt;anonymous&amp;gt; (module.js:470:10)&lt;/pre&gt;

&lt;h2&gt;Wrapping Up&lt;/h2&gt;

&lt;p&gt;This is just scratching the surface here, and the example's trivial. As I mentioned earlier, I think the real power of Node is in taking advantage of its event-driven, asynchronous model, and I'm interested to see how smart people like you will take advantage of the fact that you can now get it up and running - inside your ASP.NET applications, even, if you want - in just a few minutes.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8013234" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=2IwxKMiUZxw:B8CHWGMAgFE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=2IwxKMiUZxw:B8CHWGMAgFE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=2IwxKMiUZxw:B8CHWGMAgFE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=2IwxKMiUZxw:B8CHWGMAgFE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=2IwxKMiUZxw:B8CHWGMAgFE:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=2IwxKMiUZxw:B8CHWGMAgFE:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=2IwxKMiUZxw:B8CHWGMAgFE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/2IwxKMiUZxw" height="1" width="1"/&gt;</description><enclosure url="http://herdingcode.com/wp-content/uploads/HerdingCode-0102-Tim-Caswell-on-Node-js.mp3" length="37266544" type="audio/mpeg" /><media:content url="http://herdingcode.com/wp-content/uploads/HerdingCode-0102-Tim-Caswell-on-Node-js.mp3" fileSize="37266544" type="audio/mpeg" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> Node.js is an event-driven I/O server-side JavaScript environment based on the open-source V8 Javascript engine. It's really easy to run it on Windows now, and if you run it under iisnode, it's actually running under a standard IIS Handler, which means y</itunes:subtitle><itunes:summary> Node.js is an event-driven I/O server-side JavaScript environment based on the open-source V8 Javascript engine. It's really easy to run it on Windows now, and if you run it under iisnode, it's actually running under a standard IIS Handler, which means you can integrate it directly into ASP.NET applications. Node event-driven model is really interesting. There's been a lot of discussion on it lately; it's neither a cancer nor the cure for cancer, but it makes it easier to handle scaling in the small. While you can handle asynchrony in most web frameworks, it's a fundamental part of Node. There's plenty of information out there on what Node is and how it's used, so I'm going to skip over that and reference a few good introductory posts: What is Node.js? Node.js, Doctor’s Offices and Fast Food Restaurants – Understanding Event-driven Programming Installing and Running node.js applications within IIS on Windows - Are you mad? Some background: Herding Code podcasts, early experiments While Node has been mentioned enough on the Herding Code podcast enough that listeners have told it's been incorporated into the (unofficial) Herding Code drinking game, we've only had two official shows dedicated to Node so far. Our first Node show (Herding Code 102, Jan 2011) was with Tim Caswell, who runs the How To Node community blog site. I really appreciated Tim's overview, spanning from the basics of Node up through some more advanced uses. If you'd like an introduction to Node, I'd recommend listening to our interview with Tim - the portion of the show where he explained why Node is useful was clear enough that it got picked up by Read Write Web in a post titled Wait, What's Node Good for Again? Listen: Herding Code 102: Tim Caswell on Node.js In preparation for that interview, I followed some of Tim's tutorials and wrote my first Node code. In order to do that, I spun up an Ubuntu VM, because until recently Node didn't run very well on Windows. Since then I'd poked at it from time to time, but since it didn't really fit with my day-to-day development stack it was mostly an academic exercise. The Windows port and libuv That started to change this past June, when Ryan Dahl announced that Microsoft was partnering with Joyent to port Node to run natively on Windows. In Ryan's post, he mentioned that Bert Belder would be one of the developers working on that port, and earlier this month I posted our second Node show interviewing Bert. Bert talked about a lot of behind-the-scenes details about the port including: libuv Node previously ran on top of libev, which is Unix-only. That's now changed to use the new libuv platform library. libuv‘s purpose is to abstract platform-dependent code in Node into one place where it can be tested for correctness and performance before bindings to V8 are added. Since Node is totally non-blocking, libuv turns out to be a rather useful library itself: a BSD-licensed, minimal, high-performance, cross-platform networking library. It's nice to see that this is paying off already - from the number of cross-platform applications listed in Ryan's post to examples like this Leveraging Node’ libuv in Windows Azure example on MSDN. I/O Completion Ports Windows included support for simultaneous, asynchronous I/O with Input / Output Completion Ports (IOCP) way back in Windows NT 3.5 (circa 1994), so part of the work in getting Node running on Windows required adding IOCP support to libuv. Cygwin There was a previous version of Node that ran on Cygwin, for certain values of &amp;quot;ran.&amp;quot; I really appreciated Bert's response when asked whether they were able to use Cygwin in this port: it was exactly the opposite of what they were hoping to accomplish. Cygwin uses a compatibility layer to allow Unix applications run on Windows, which isn't ideal for performance. In contrast, this Node effort is focused on leveraging the native platform as much as possible. Listen: Herding Code 122: Bert Belder on porting node.js to Windows R</itunes:summary><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/10/26/using-node-js-in-an-asp-net-mvc-application-with-iisnode.aspx</feedburner:origLink></item><item><title>Taking a look at the HTML5 video use in the Bing video homepage</title><link>http://feedproxy.google.com/~r/jongalloway/~3/GG5TlS2wpXs/taking-a-look-at-the-html5-video-use-in-the-recent-bing-video-homepage.aspx</link><pubDate>Wed, 12 Oct 2011 09:40:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7990585</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=7990585</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/10/12/taking-a-look-at-the-html5-video-use-in-the-recent-bing-video-homepage.aspx#comments</comments><description>&lt;p&gt;I've always liked the pictures on the Bing homepage. In late September, they started occasionally replacing the picture with an HTML5 video. &lt;a href="http://www.bing.com/community/site_blogs/b/search/archive/2011/09/23/something-new-on-the-homepage.aspx" mce_href="http://www.bing.com/community/site_blogs/b/search/archive/2011/09/23/something-new-on-the-homepage.aspx"&gt;The Bing team blogged about it&lt;/a&gt;, and included &lt;a href="http://www.microsoft.com/Presspass/Features/2011/sep11/09-23Bing.mspx" mce_href="http://www.microsoft.com/Presspass/Features/2011/sep11/09-23Bing.mspx"&gt;an interesting&amp;nbsp;video from the managing editor for the Bing homepage&lt;/a&gt;&amp;nbsp;that talks about how they select photos and why they're going to start adding the occasional video backgrounds.&lt;/p&gt; &lt;p&gt;I've been interested in HTML5 video implementations since I first started playing with them in the Firefox 3.x nightly builds. Since the Bing page was presumably designed to handle "industrial strength" use - many browsers, high performance, bandwidth consideration - I thought I'd peek under the hood and see how things were set up. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: While I also work for Microsoft, I don't have any inside info on how or why they set things up as they did - I'm just some random guy on the internet for the duration of this post.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The homepage changes every day, but you can click back to previous homepages using the back arrow in the bottom right:&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-09-28 13h34_51" href="http://www.flickr.com/photos/36836555@N00/6193240976/" mce_href="http://www.flickr.com/photos/36836555@N00/6193240976/"&gt;&lt;img border="0" alt="2011-09-28 13h34_51" src="http://farm7.static.flickr.com/6121/6193240976_bd73437bab_b.jpg" mce_src="http://farm7.static.flickr.com/6121/6193240976_bd73437bab_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;HTML5 Video as a design element&lt;/h2&gt;  &lt;p&gt;The obvious use of HTML5 video is in the traditional video player experience, like the &lt;a href="http://www.youtube.com/html5" mce_href="http://www.youtube.com/html5"&gt;YouTube HTML5 video player&lt;/a&gt;. It's interesting to see &amp;lt;video&amp;gt; used as a design element here, just like the good old &amp;lt;img&amp;gt; tag. It's not content to be viewed, it's not essential to the page, but it's a nice touch - providing it's used subtly and tastefully, which is definitely the case here. I'm this kind of thinking providing it doesn't adversely affect the user experience in other ways, so I'll look at that more next.&lt;/p&gt;  &lt;h2&gt;HTML5 Video tag overlaying an image&lt;/h2&gt;  &lt;p&gt;First, I noticed that the &amp;lt;video&amp;gt; tag is on top of a &amp;lt;div&amp;gt; which has background image set via CSS. I think this is a good idea for a few reasons:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Nice preload experience for the video &lt;/li&gt;    &lt;li&gt;Nice fallback experience if the video can't be shown &lt;!--EndFragment--&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Nice preload experience for the video&lt;/h3&gt;  &lt;p&gt;Since the image is the first frame of the video, the user experience is really smooth - a nice image is shown immediately, and the when the video loads and plays, it's a very smooth transition.&lt;/p&gt;  &lt;h3&gt;Nice fallback experience if the video can't be shown&lt;/h3&gt;  &lt;p&gt;In case the video doesn't load, can't be displayed, Javascript is disabled, etc., the image background is just fine as a fallback. &lt;/p&gt;  &lt;p&gt;This wouldn't work well if the video were essential content. In that case, I'd use &lt;a href="http://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#embedded-content" mce_href="http://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#embedded-content"&gt;embedded content&lt;/a&gt; in the &amp;lt;video&amp;gt; tag to fallback in the case the video tag can't be rendered. Using embedded content for is a subject for another post, but the the idea is that you can put content inside a tag, and browsers will automatically fall back to the embedded content if they can't display the parent, like this:&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;!-- Example - not in the Bing source --&amp;gt;&lt;/pre&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;video&amp;gt;
    &amp;lt;source src="video.ogg" type="video/ogg" /&amp;gt;
    &amp;lt;source src="video.mp4" type="video/mp4" /&amp;gt;
    &amp;lt;embed  src=&lt;a href="http://site.com/video/player" mce_href="http://site.com/video/player"&gt;http://site.com/video/player&lt;/a&gt; 
            type="application/x-shockwave-flash" 
            allowfullscreen="true"&amp;gt;
       &amp;lt;/embed&amp;gt;
&amp;lt;/video&amp;gt;&lt;/pre&gt;

&lt;p&gt;So in this case, we've got a &amp;lt;div&amp;gt; (background image set via CSS) which contains a &amp;lt;video&amp;gt; tag:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;div style='height: 472px;' id='bgDiv'&amp;gt;
    &amp;lt;video id='vid' 
           onended='VM.play();' 
           preload='auto' 
           loop='true' 
           autobuffer='true'
           width='956' 
           height='512'&amp;gt;
    &amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;The #bgDiv background is set to the background image: &lt;a title="http://www.bing.com/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US56140151.jpg" href="http://www.bing.com/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US56140151.jpg" mce_href="http://www.bing.com/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US56140151.jpg"&gt;http://www.bing.com/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US56140151.jpg&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Video Source&lt;/h2&gt;

&lt;p&gt;Due to some conflicts in codec licensing, there's no one video codec that will work on all browsers. Cross-browser HTML5 video requires several media source types. There are &lt;a href="http://en.wikipedia.org/wiki/HTML5_video#Multiple_sources" mce_href="http://en.wikipedia.org/wiki/HTML5_video#Multiple_sources"&gt;two ways to handle the multiple source issue&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Using any number of &amp;lt;source&amp;gt; elements, as shown below, the browser will choose automatically which file to download. Alternatively, the &lt;a href="http://en.wikipedia.org/wiki/Javascript" mce_href="http://en.wikipedia.org/wiki/Javascript"&gt;javascript&lt;/a&gt; canPlay() function can be used to achieve the same. The "type" attribute specifies the &lt;a href="http://en.wikipedia.org/wiki/Internet_media_type" mce_href="http://en.wikipedia.org/wiki/Internet_media_type"&gt;MIME type&lt;/a&gt; and possibly a list of codecs, which helps the browser to determine whether it can decode the file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the declarative way to handle this is to nest multiple source elements in the video, like this:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;video poster="movie.jpg" controls&amp;gt;
        &amp;lt;source src='movie.webm' type='video/webm; codecs="vp8.0, vorbis"'/&amp;gt;
        &amp;lt;source src='movie.ogv' type='video/ogg; codecs="theora, vorbis"'/&amp;gt;
        &amp;lt;source src='movie.mp4' type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'/&amp;gt;
        &amp;lt;p&amp;gt;This is fallback content&amp;lt;/p&amp;gt;
&amp;lt;/video&amp;gt;&lt;/pre&gt;

&lt;p&gt;That's what I'm more used to seeing. The Bing implementation use the other, imperative option. When loading, it uses Javascript to query for supported video types and loads based on the result. First, the three main video types are loaded into an array:&lt;/p&gt;

&lt;pre class="brush: js; auto-links: false;"&gt;var g_vid = [
    ["video\/webm; codecs=\"vp8, vorbis\"", "\/az\/hprichv\/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US.webm"],
    ["video\/ogg; codecs=\"theora, vorbis\"", "\/az\/hprichv\/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US.ogv"],
    ["video\/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"", "\/az\/hprichv\/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US.mp4"]
];&lt;/pre&gt;

&lt;p&gt;Next, an onload function for the video element decides which source to load:&lt;/p&gt;

&lt;pre class="brush: js; auto-links: false;"&gt;this.sa_vid_ld = function (e) {
    try {
        a = _ge("vid");
        if (this.Loaded || _w.g_vid == undefined || _w.g_vid == null || a == null) return;
        var d = _w.g_vid;
        sj_be(a, "canplaythrough", e ? e : VM.fade);
        sj_so(a, 0);
        a.width = VM.Constants.VideoWidth;
        a.height = VM.Constants.VideoHeight;
        for (var b = 0; b &amp;lt; d.length; b++) if ( !! (a.canPlayType &amp;amp;&amp;amp; a.canPlayType(d[b][0]).match(/^(probably|maybe)$/i))) {
            a.type = d[b][0];
            a.src = d[b][1];
            c = sb_gt();
            break
        }
    } catch (f) {
        HPV_er(f, "Load")
    }
}&lt;/pre&gt;

&lt;p&gt;Note the interesting match on canPlayType - since browsers may rely on external codecs, calling &lt;a href="http://msdn.microsoft.com/en-us/library/ff975191(v=VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ff975191(v=VS.85).aspx"&gt;canPlayType on a codec type can return probably, maybe, or an empty string&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Browser sniffing&lt;/p&gt;

&lt;p&gt;There's definitely some server-side browser sniffing going on here. Normally I frown on that kind of thing, but for high-volume bandwidth-sensitive search engine home pages, all bets are off. View source on &lt;a href="http://google.com" mce_href="http://google.com"&gt;http://google.com&lt;/a&gt; - it's not pretty either, and I'm certain smarter people than me have looked at both of these home pages in great detail.&lt;/p&gt;

&lt;p&gt;I think this is similar to database denormalization (assuming you're into normalized databased) - a general rule applies under general conditions, but the general rules go out the window in special circumstances. Normally I'd call web developers crazy for writing custom (non-jQuery) selector logic, but Bing and Google both eschew jQuery.&lt;/p&gt;

&lt;p&gt;I compared the HTML for the Bing homepage when using IE9 and &lt;a href="http://www.enhanceie.com/ietoys/uapick.asp" mce_href="http://www.enhanceie.com/ietoys/uapick.asp"&gt;IE9 with a IE6 user-agent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a title="2011-10-12 01h53_53" href="http://www.flickr.com/photos/36836555@N00/6236726631/" mce_href="http://www.flickr.com/photos/36836555@N00/6236726631/"&gt;&lt;img border="0" alt="2011-10-12 01h53_53" src="http://farm7.static.flickr.com/6214/6236726631_615679ce92_b.jpg" mce_src="http://farm7.static.flickr.com/6214/6236726631_615679ce92_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When browsing with an IE6 user-agent, Bing doesn't send the &amp;lt;video&amp;gt; tag. Additionally, it sets a g_hasVid boolean variable so there's no attempt to determine video capabilities and set the source.&lt;/p&gt;

&lt;p&gt;Again, while this would normally get me worked up, I can see the wisdom in minimizing the content written to the browser.&lt;/p&gt;

&lt;h2&gt;Looping and HTTP 304&lt;/h2&gt;

&lt;p&gt;The &amp;lt;video&amp;gt; tag is set to automatically loop. Note the loop="true" in the video tag below:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;div style='height: 472px;' id='bgDiv'&amp;gt;
    &amp;lt;video id='vid' 
           onended='VM.play();' 
           preload='auto' 
           loop='true' 
           autobuffer='true'
           width='956' 
           height='512'&amp;gt;
    &amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;Profiling the page, though, I see that there are continued requests for the video. The page is correctly using a HTTP 304 (not modified) response, so that the locally cached video is reused:&lt;/p&gt;

&lt;table border="0" cellSpacing="0" cellPadding="0"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;
        &lt;p&gt;URL&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Method&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Result&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Type&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Received&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Taken&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Initiator&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Wait&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Start&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Request&lt;/p&gt;
      &lt;/th&gt;

      &lt;th&gt;
        &lt;p&gt;Response&lt;/p&gt;
      &lt;/th&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;
        &lt;p&gt;/fd/ls/GLinkPing.aspx?IG=8226ea3583704baaac8a91619295f16b&amp;amp;ID=SERP,5033.1&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;GET&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;200&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;image/gif&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;250 B&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;171 ms&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;&amp;lt;img&amp;gt;&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;1981&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;78&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;78&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;15&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;
        &lt;p&gt;/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US56140151.jpg&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;GET&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;200&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;image/jpeg&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;80.01 KB&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;266 ms&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;background-image&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;2620&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;47&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;219&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;
        &lt;p&gt;/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US.webm&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;GET&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;200&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;video/webm&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;1.58 MB&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;1.03 s&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;&amp;nbsp;&lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;2636&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;62&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;968&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;
        &lt;p&gt;/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US.webm&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;GET&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;304&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;video/webm&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;219 B&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;16 ms&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;&amp;nbsp;&lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;13915&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;16&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;
        &lt;p&gt;/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US.webm&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;GET&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;304&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;video/webm&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;219 B&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;&amp;lt; 1 ms&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;&amp;nbsp;&lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;19016&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;
        &lt;p&gt;/az/hprichv/?p=OctLeaves_Artbeat_PF-FH103-79_EN-US.webm&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;GET&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;304&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;video/webm&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;219 B&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;15 ms&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;&amp;nbsp;&lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;24102&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;0&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p&gt;15&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7990585" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=GG5TlS2wpXs:X6Yd9UoBoPk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=GG5TlS2wpXs:X6Yd9UoBoPk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=GG5TlS2wpXs:X6Yd9UoBoPk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=GG5TlS2wpXs:X6Yd9UoBoPk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=GG5TlS2wpXs:X6Yd9UoBoPk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=GG5TlS2wpXs:X6Yd9UoBoPk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=GG5TlS2wpXs:X6Yd9UoBoPk:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/GG5TlS2wpXs" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/html5/default.aspx">html5</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/10/12/taking-a-look-at-the-html5-video-use-in-the-recent-bing-video-homepage.aspx</feedburner:origLink></item><item><title>ASP.NET website redesign beta: What's changed, why, and how you can make it better</title><link>http://feedproxy.google.com/~r/jongalloway/~3/l_cfgtObRps/asp-net-website-redesign-beta-what-s-changed-why-and-how-you-can-make-it-better.aspx</link><pubDate>Mon, 10 Oct 2011 23:24:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7989233</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=7989233</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/10/10/asp-net-website-redesign-beta-what-s-changed-why-and-how-you-can-make-it-better.aspx#comments</comments><description>&lt;p&gt;We're happy to announce the beta release of something we've been quietly working on for a while now: a redesign for the ASP.NET website (&lt;a href="http://asp.net" mce_href="http://asp.net"&gt;http://asp.net&lt;/a&gt;). You can browse directly to it at &lt;a href="http://beta.asp.net" mce_href="http://beta.asp.net"&gt;http://beta.asp.net&lt;/a&gt;, or if you're on the &lt;a href="http://asp.net" mce_href="http://asp.net"&gt;http://asp.net&lt;/a&gt; site you can click on the "Try the NEW beta site" link in the header.&lt;/p&gt;  &lt;p&gt;&lt;a title="beta.asp.net - home" href="http://www.flickr.com/photos/36836555@N00/6231619133/" mce_href="http://www.flickr.com/photos/36836555@N00/6231619133/"&gt;&lt;img border="0" alt="beta.asp.net - home" src="http://farm7.static.flickr.com/6223/6231619133_93f487253d.jpg" mce_src="http://farm7.static.flickr.com/6223/6231619133_93f487253d.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Goal: Make it easier to find useful information &lt;/h2&gt;  &lt;p&gt;&lt;a href="http://www.hanselman.com/blog/RFCNewBetaASPnetWebsite.aspx" mce_href="http://www.hanselman.com/blog/RFCNewBetaASPnetWebsite.aspx"&gt;Scott Hanselman listed some of the goals of this new design in his post&lt;/a&gt;:&lt;/p&gt;  &lt;ul&gt;   &lt;ul&gt;     &lt;li&gt;&lt;b&gt;A newer Information Architecture&lt;/b&gt; (IA) that scales with different types of content. Trying to get you somewhere &lt;em&gt;useful &lt;/em&gt;quickly. &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Content organized into relevant topic areas&lt;/strong&gt; (Overview, Videos, Tutorials, etc.) to make information easier to find and to learn a technology. &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Improved on boarding experience&lt;/strong&gt; – Developers new to ASP.NET should find it easier to get started and download what they need. &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Important Samples and Tutorials&lt;/strong&gt; are positioned prominently in the structure of the site so that they are easier to find. &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Textual Tutorials are as important as videos &lt;/strong&gt;- We've heard people want text tutorials more than videos, so we're finding balance between these two kind of content. &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Improved Social Integration – &lt;/strong&gt;&lt;a href="http://beta.asp.net/community" mce_href="http://beta.asp.net/community"&gt;Community info&lt;/a&gt;, pulling from Twitter, Facebook and blogs. &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;A less cluttered user experience&lt;/strong&gt; to get you where you need to go in fewer clicks. &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Open Source and Samples &lt;/strong&gt;- We're looking for new ways to showcase great open source projects and excellent &lt;a href="http://code.msdn.com" mce_href="http://code.msdn.com"&gt;samples&lt;/a&gt;. &lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;The main point is in trying to make it easier for you to find useful content. ASP.NET's capabilities have grown quite a bit over the years, and there's a ton of content spanning technologies (ASP.NET Web Forms, ASP.NET MVC, ASP.NET Web Pages), skill levels (getting started through advanced), content types (reference material, tutorials, blogs).&lt;/p&gt;  &lt;p&gt;While it's tempting to focus on the home page, the goal is more apparent when you drill into the content. For instance, if you're looking for information about Models in ASP.NET MVC, the existing site has historically made you play hide and seek a bit. We've recently been working to provide some structure around the content, as you can see in the Learning Resources section on &lt;a href="http://asp.net/mvc" mce_href="http://asp.net/mvc"&gt;http://asp.net/mvc&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a title="asp.net site - MVC page" href="http://www.flickr.com/photos/36836555@N00/6232327962/" mce_href="http://www.flickr.com/photos/36836555@N00/6232327962/"&gt;&lt;img border="0" alt="asp.net site - MVC page" src="http://farm7.static.flickr.com/6043/6232327962_29e4335c3e_b.jpg" mce_src="http://farm7.static.flickr.com/6043/6232327962_29e4335c3e_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The new beta.asp.net site goes a lot farther, elevating that content outline structure more directly into the site:&lt;/p&gt;  &lt;p&gt;&lt;a title="beta.asp.net - Content page" href="http://www.flickr.com/photos/36836555@N00/6231621799/" mce_href="http://www.flickr.com/photos/36836555@N00/6231621799/"&gt;&lt;img border="0" alt="beta.asp.net - Content page" src="http://farm7.static.flickr.com/6042/6231621799_aa582a62ff_b.jpg" mce_src="http://farm7.static.flickr.com/6042/6231621799_aa582a62ff_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There was a time, not all that long ago, when adding a new "page" to the site required adding a new &lt;em&gt;page&lt;/em&gt; to the site. As in, adding any content required development and deployment. &lt;a href="http://weblogs.asp.net/jgalloway/archive/2010/03/11/the-new-asp-net-website.aspx" mce_href="http://weblogs.asp.net/jgalloway/archive/2010/03/11/the-new-asp-net-website.aspx"&gt;In May 2010, I posted about a site redesign which started the work of trying to better organize and surface content&lt;/a&gt;, but as we weren't fully on a content management system then it wasn't as possible to really reorganize content as much as we wanted. Now that the content's managed by a &lt;a href="http://umbraco.com/" mce_href="http://umbraco.com/"&gt;content management system&lt;/a&gt;, we can not only create and manage content more quickly, we can move it around.&lt;/p&gt;  &lt;h2&gt;A fresher design&lt;/h2&gt;  &lt;p&gt;I'm happy to see a much cleaner, clearer, and more modern design. As I just mentioned, &lt;a href="http://weblogs.asp.net/jgalloway/archive/2010/03/11/the-new-asp-net-website.aspx" mce_href="http://weblogs.asp.net/jgalloway/archive/2010/03/11/the-new-asp-net-website.aspx"&gt;we last updated the site 17 months ago&lt;/a&gt;. For a comparison, here are side-by-side shots of the home page comparing the &lt;a href="http://web.archive.org/web/20100309160902/http://www.asp.net/" mce_href="http://web.archive.org/web/20100309160902/http://www.asp.net/"&gt;previous&lt;/a&gt;, &lt;a href="http://asp.net" mce_href="http://asp.net"&gt;current&lt;/a&gt;, and &lt;a href="http://beta.asp.net" mce_href="http://beta.asp.net"&gt;beta&lt;/a&gt; designs.&lt;/p&gt;  &lt;p&gt;Old:&lt;/p&gt;  &lt;p style="clear: left;"&gt;&lt;a title="ASP.NET Home Page - Circa May 2010" href="http://www.flickr.com/photos/36836555@N00/6232025427/" mce_href="http://www.flickr.com/photos/36836555@N00/6232025427/"&gt;&lt;img border="0" alt="ASP.NET Home Page - Circa May 2010" src="http://farm7.static.flickr.com/6216/6232025427_4b3fdf7197_b.jpg" mce_src="http://farm7.static.flickr.com/6216/6232025427_4b3fdf7197_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p style="clear: left;"&gt;Current:&lt;/p&gt;  &lt;p style="clear: left;"&gt;&lt;a title="ASP.NET Home Page (circa Oct 2011)" href="http://www.flickr.com/photos/36836555@N00/6232010965/" mce_href="http://www.flickr.com/photos/36836555@N00/6232010965/"&gt;&lt;img border="0" alt="ASP.NET Home Page (circa Oct 2011)" src="http://farm7.static.flickr.com/6036/6232010965_cbcdcb36d7.jpg" mce_src="http://farm7.static.flickr.com/6036/6232010965_cbcdcb36d7.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p style="clear: left;"&gt;Beta:&lt;/p&gt;  &lt;p&gt;&lt;a title="beta.asp.net - home" href="http://www.flickr.com/photos/36836555@N00/6231619133/" mce_href="http://www.flickr.com/photos/36836555@N00/6231619133/"&gt;&lt;img border="0" alt="beta.asp.net - home" src="http://farm7.static.flickr.com/6223/6231619133_93f487253d.jpg" mce_src="http://farm7.static.flickr.com/6223/6231619133_93f487253d.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And here's how the ASP.NET MVC content has evolved over time (screenshots showing more drilldown with each release).&lt;/p&gt;  &lt;p&gt;Old:&lt;/p&gt;  &lt;div&gt;&lt;a href="http://www.flickr.com/photos/36836555@N00/4423727105/" mce_href="http://www.flickr.com/photos/36836555@N00/4423727105/"&gt;&lt;img border="0" src="http://farm5.static.flickr.com/4071/4423727105_075ca81195_d.jpg" mce_src="http://farm5.static.flickr.com/4071/4423727105_075ca81195_d.jpg"&gt;&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;Current:&lt;/div&gt;  &lt;div&gt;&lt;a title="asp.net site - MVC page" href="http://www.flickr.com/photos/36836555@N00/6232327962/" mce_href="http://www.flickr.com/photos/36836555@N00/6232327962/"&gt;&lt;img border="0" alt="asp.net site - MVC page" src="http://farm7.static.flickr.com/6043/6232327962_29e4335c3e_b.jpg" mce_src="http://farm7.static.flickr.com/6043/6232327962_29e4335c3e_b.jpg"&gt;&lt;/a&gt;&lt;/div&gt;  &lt;div&gt;Beta:&lt;/div&gt;  &lt;div&gt;&lt;a title="beta.asp.net - Content page" href="http://www.flickr.com/photos/36836555@N00/6231621799/" mce_href="http://www.flickr.com/photos/36836555@N00/6231621799/"&gt;&lt;img border="0" alt="beta.asp.net - Content page" src="http://farm7.static.flickr.com/6042/6231621799_aa582a62ff_b.jpg" mce_src="http://farm7.static.flickr.com/6042/6231621799_aa582a62ff_b.jpg"&gt;&lt;/a&gt;&lt;/div&gt;  &lt;h2&gt;Community content&lt;/h2&gt;  &lt;p&gt;I've always wished we did a better job of surfacing our community content, and I'm very happy with the progress on &lt;a title="http://beta.asp.net/community" href="http://beta.asp.net/community" mce_href="http://beta.asp.net/community"&gt;http://beta.asp.net/community&lt;/a&gt;. I'm going with the tiny screenshot here since there's a lot of content, but I love how this shows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Daily Spotlight&lt;/li&gt;    &lt;li&gt;Article of the Day&lt;/li&gt;    &lt;li&gt;News&lt;/li&gt;    &lt;li&gt;Community Blogs&lt;/li&gt;    &lt;li&gt;Microsoft Blogs&lt;/li&gt;    &lt;li&gt;Events&lt;/li&gt;    &lt;li&gt;Twitter&lt;/li&gt;    &lt;li&gt;Forum highlights&lt;/li&gt;    &lt;li&gt;New Wiki Articles&lt;/li&gt;    &lt;li&gt;Community Samples&lt;/li&gt;    &lt;li&gt;Control Gallery updates&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a title="beta.asp.net - community page" href="http://www.flickr.com/photos/36836555@N00/6232223104/" mce_href="http://www.flickr.com/photos/36836555@N00/6232223104/"&gt;&lt;img border="0" alt="beta.asp.net - community page" src="http://farm7.static.flickr.com/6215/6232223104_05a12ede49.jpg" mce_src="http://farm7.static.flickr.com/6215/6232223104_05a12ede49.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Feedback, plz!&lt;/h2&gt;  &lt;p&gt;Okay, I told you what we hoped to accomplish. How's we do? This is a beta, and we're honestly, earnestly seeking your feedback. &lt;/p&gt;  &lt;p&gt;The best way to give your feedback (much better than a blog comment!) is to post your feedback on the &lt;a href="http://aspnet.uservoice.com/forums/136460-www-asp-net-website-" mce_href="http://aspnet.uservoice.com/forums/136460-www-asp-net-website-"&gt;dedicated UserVoice forum for the ASP.NET website&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7989233" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=l_cfgtObRps:xVDXS6riJ24:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=l_cfgtObRps:xVDXS6riJ24:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=l_cfgtObRps:xVDXS6riJ24:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=l_cfgtObRps:xVDXS6riJ24:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=l_cfgtObRps:xVDXS6riJ24:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=l_cfgtObRps:xVDXS6riJ24:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=l_cfgtObRps:xVDXS6riJ24:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/l_cfgtObRps" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/jgalloway/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/10/10/asp-net-website-redesign-beta-what-s-changed-why-and-how-you-can-make-it-better.aspx</feedburner:origLink></item><item><title>ASP.NET MVC 4 Overview - Part 2: Default template changes and Adaptive Rendering using Viewport and CSS Media Queries</title><link>http://feedproxy.google.com/~r/jongalloway/~3/lDNRaOKBm4k/asp-net-mvc-4-overview-part-2-default-template-changes-and-adaptive-rendering.aspx</link><pubDate>Thu, 06 Oct 2011 15:19:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7983727</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=7983727</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/10/06/asp-net-mvc-4-overview-part-2-default-template-changes-and-adaptive-rendering.aspx#comments</comments><description>&lt;p&gt;This is Part 2 of a series overviewing changes in &lt;a href="http://asp.net/mvc/mvc4" mce_href="http://asp.net/mvc/mvc4"&gt;ASP.NET MVC 4&lt;/a&gt;. &lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/09/23/asp-net-mvc-4-overview-part-1-installing-asp-net-mvc-4-and-creating-a-new-project.aspx" mce_href="http://weblogs.asp.net/jgalloway/archive/2011/09/23/asp-net-mvc-4-overview-part-1-installing-asp-net-mvc-4-and-creating-a-new-project.aspx"&gt;In Part 1, we looked at installation and new options in creating a new project&lt;/a&gt;. In Part 2, we'll look at changes to the default project template and how it uses adaptive rendering to optimize the display for the end user's browser dimensions.&lt;/p&gt;  &lt;p&gt;When we left off, we'd just run through the File / New Project / New ASP.NET MVC 4 Web Application / Internet Application and created a new project. Up through this point, the process has looked pretty similar to the ASP.NET MVC 3 experience with a few new options. &lt;/p&gt;  &lt;p&gt;When we run the application, though, things start looking significantly different. I'll compare what's different, then explain why this will help you build mobile-ready sites more effectively.&lt;/p&gt;  &lt;h2&gt;Review: The ASP.NET MVC 3 template&lt;/h2&gt;  &lt;p&gt;Just in case you need a reminder, the ASP.NET MVC 3 default template looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/36836555@N00/6209849795/" mce_href="http://www.flickr.com/photos/36836555@N00/6209849795/"&gt;&lt;img border="0" src="http://farm7.static.flickr.com/6113/6209849795_dbcd931c02_b.jpg" width="938" height="412" mce_src="http://farm7.static.flickr.com/6113/6209849795_dbcd931c02_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The astute ASP.NET MVC historians among you will note that the ASP.NET MVC 3 default template was very similar to the default template in ASP.NET 1 and 2, with two very subtle changes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The corners on the boxes are rounded (subtle - but nice - improvement using &lt;a href="http://www.w3.org/TR/css3-background/#corners" mce_href="http://www.w3.org/TR/css3-background/#corners"&gt;CSS 3 border-radius&lt;/a&gt;) &lt;/li&gt;    &lt;li&gt;Viewing source source reveals that the page is constructed using &lt;a href="http://msdn.microsoft.com/en-us/scriptjunkie/gg454786" mce_href="http://msdn.microsoft.com/en-us/scriptjunkie/gg454786"&gt;HTML5 semantic elements&lt;/a&gt; (header, nav, section, footer) which are backwards compatible due to use of the Modernizr library &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Overall, I think it's fair to say that the ASP.NET MVC default template has been functional but austere, and perhaps a bit dated. No more!&lt;/p&gt;  &lt;h2&gt;The ASP.NET MVC 4 Default Template: Updated design &lt;/h2&gt;  &lt;p&gt;There's a completely new design here. It's still relatively simple, but it actually looks like a web page you might see on the public internet.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/36836555@N00/6199418187/" mce_href="http://www.flickr.com/photos/36836555@N00/6199418187/"&gt;&lt;img border="0" src="http://farm7.static.flickr.com/6162/6199418187_74e9081912_b.jpg" mce_src="http://farm7.static.flickr.com/6162/6199418187_74e9081912_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;The obvious - new colors and fonts&lt;/h3&gt;  &lt;p&gt;This design actually looks like an actual web designer was involved, which is nice. The fonts have improved, too. For example, the preferred body font has changed from Trubuchet MS to Segoe UI.&lt;/p&gt;  &lt;h3&gt;Look, Mom! Three columns!&lt;/h3&gt;  &lt;p&gt;I'm personally happy to see some columns in the default template without using a grid system or a table (a.k.a yesteryear's grid system). While you may immediately remove this page most of the time, I'm glad that folks can see a nice, clean implementation of columnar layout.&lt;/p&gt;  &lt;h3&gt;Hmm... images?&lt;/h3&gt;  &lt;p&gt;The previous templates have always been CSS-only designs with no images, and I was a little surprised to see images in this default template. I talked to &lt;a href="http://blog.osbornm.com/" mce_href="http://blog.osbornm.com/"&gt;Matthew Osborn&lt;/a&gt;, an ASP.NET team member who worked on this new design, at the BUILD conference in September. He told me that the tradeoff there was that doing anything fancy with the CSS - such as creating the numbered bullets using border-radius - would have resulted in CSS that wasn't very reusable. On the other hand, the images are easily removable or replaceable. After talking to him a bit, this makes good sense to me.&lt;/p&gt;  &lt;h2&gt;Adaptive Rendering using CSS Media Queries&lt;/h2&gt;  &lt;p&gt;While the new visual design is welcome and interesting, it'll probably get replaced in most real applications. The really interesting bit here is the adaptive rendering. To see how what that means, think about how the ASP.NET MVC 3 (and below) default templates look in a mobile browser (or in this case, the &lt;a href="http://msdn.microsoft.com/en-us/library/ff402563(v=VS.92).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ff402563(v=VS.92).aspx"&gt;Windows Phone Emulator&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm7.static.flickr.com/6165/6213578548_082f34017c_b.jpg" mce_src="http://farm7.static.flickr.com/6165/6213578548_082f34017c_b.jpg"&gt;&lt;/p&gt;  &lt;p&gt;The design's clearly not optimized for a mobile device, and zooming in so you can read the tiny print doesn't help that much since the text doesn't reflow.&lt;/p&gt;  &lt;p&gt;Let's take a look at the ASP.NET MVC 4 default template in a mobile browser:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/36836555@N00/6213084113/" mce_href="http://www.flickr.com/photos/36836555@N00/6213084113/"&gt;&lt;img border="0" src="http://farm7.static.flickr.com/6232/6213084113_c2b7125c94_b.jpg" mce_src="http://farm7.static.flickr.com/6232/6213084113_c2b7125c94_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What's immediately obvious is that this page is intelligently scaled to the screen size of the mobile device. Rather than just scaling the page down (shrinking text and all), the page is redrawn so that it's usable at in the device's dimensions.&lt;/p&gt;  &lt;p&gt;What might not be immediately obvious is that the page layout actually changes subtly at this smaller size to optimize for the new dimensions. Some examples from the header area:&lt;/p&gt;  &lt;ul&gt;   &lt;ul&gt;     &lt;li&gt;The logo is aligned left in the desktop view, centered in the mobile view &lt;/li&gt;      &lt;li&gt;The registration / login links are aligned to the top right in the desktop view, and are both centered and dropped below the logo &lt;/li&gt;      &lt;li&gt;The Home / About / Contact links are aligned &lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;Scrolling down further, you can see the other simplifications to the mobile view to tighten it up and maximize the screen real estate.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm7.static.flickr.com/6229/6215354293_ecc04db2b9_b.jpg" mce_src="http://farm7.static.flickr.com/6229/6215354293_ecc04db2b9_b.jpg"&gt;&lt;img src="http://farm7.static.flickr.com/6173/6215878428_c6f9bb41e6_b.jpg" mce_src="http://farm7.static.flickr.com/6173/6215878428_c6f9bb41e6_b.jpg"&gt;&lt;/p&gt;  &lt;p&gt;While the changes are subtle, they make a difference. Examples:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The round bullet icons in the "We suggest the following" list are removed in the mobile view &lt;/li&gt;    &lt;li&gt;The footer is centered, and the Facebook / Twitter logos are&amp;nbsp; replaced by small text &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Adaptive Rendering&lt;/h2&gt;  &lt;p&gt;These templates are using what's known as &lt;em&gt;adaptive rendering&lt;/em&gt; to automatically &lt;strong&gt;scale the page depending on page width&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Note that I didn't say that the application is scaling the page by guessing if the user's on a mobile device based on headers or other clues. That's known as browser sniffing, and it's generally frowned - it's error prone, and when you guess wrong you irritate your users. Instead, this page is making use of two commonly supported browser features, the viewport meta tag and the use of CSS media queries.&lt;/p&gt;  &lt;h3&gt;The Viewport Meta Tag&lt;/h3&gt;  &lt;p&gt;The majority of web pages have been created without any thought to how they'll appear in smaller form factors, and mobile browsers have long struggled with guessing how best to display them. Designs which are primarily focused on semantically structured textual content can be reformatted to make the text readable, but sites with rigid (brittle?) visually oriented designs don't reformat well at all and need to be handled with zooming and panning.&lt;/p&gt;  &lt;p&gt;Since the majority of websites weren't designed to scale well, when mobile browsers have to guess how to render your page they'll generally fail safe and go with the zoom and pan style rendering. The solution to this problem is to use to tell the browser what your design dimensions are, so it doesn't have to guess.&lt;/p&gt;  &lt;p&gt;Often, Viewport tags are only used in pages which are specifically designed for small form factors, based on browser sniffing or user selection (see the &lt;a href="http://weblogs.asp.net/jgalloway/archive/2008/11/24/looking-back-at-microsoftpdc-com-from-the-inside.aspx" mce_href="http://weblogs.asp.net/jgalloway/archive/2008/11/24/looking-back-at-microsoftpdc-com-from-the-inside.aspx"&gt;mobile section of my post on about the Microsoft PDC 2008 site for an example&lt;/a&gt;). In this case, you'd see a Viewport tag that looks something like this:&lt;/p&gt;  &lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;meta name="viewport" content="width=320"&amp;gt;&lt;/pre&gt;

&lt;p&gt;This works for mobile-specific views, but doesn't adapt to larger sizes well.&lt;/p&gt;

&lt;p&gt;A better solution is to design your CSS to scale well at all sizes (more on that in a second), then tell the browser that the Viewport is whatever the device supports. Fortunately, that's pretty easy:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false;"&gt;&amp;lt;meta name="viewport" content="width=device-width"&amp;gt;&lt;/pre&gt;

&lt;p&gt;Notes for further study on Viewport:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Jorge Peraza (on the IE Mobile Team) has a really &lt;a href="http://blogs.msdn.com/b/iemobile/archive/2011/01/21/managing-the-browser-viewport-in-windows-phone-7.aspx" mce_href="http://blogs.msdn.com/b/iemobile/archive/2011/01/21/managing-the-browser-viewport-in-windows-phone-7.aspx"&gt;good blog post with lots of screenshots demonstrating how the Viewport tag works&lt;/a&gt;. &lt;/li&gt;

  &lt;li&gt;Joe Marini (also on the IE Mobile Team) wrote a &lt;a href="http://blogs.msdn.com/b/iemobile/archive/2010/11/22/the-ie-mobile-viewport-on-windows-phone-7.aspx" mce_href="http://blogs.msdn.com/b/iemobile/archive/2010/11/22/the-ie-mobile-viewport-on-windows-phone-7.aspx"&gt;really interesting blog post&lt;/a&gt; detailing the evolution from the &lt;em&gt;HandheldFriendly&lt;/em&gt; meta tag (Palm, AvantGo) to the &lt;em&gt;MobileOptimized&lt;/em&gt; meta tag (PocketPC) to the current &lt;em&gt;Viewport&lt;/em&gt; tag, explaining how it's improved along the way and explaining the different Viewport properties which are commonly accepted. Honest, I'm not getting any kickbacks from the IE Mobile Team blog, I just found their posts really well written. &lt;/li&gt;

  &lt;li&gt;The &lt;a href="http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html" mce_href="http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html"&gt;Safari Developer Library has a very thorough article on Viewport&lt;/a&gt;, including an excellent introductory section titled &lt;a href="http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html" mce_href="http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html"&gt;What is the Viewport?&lt;/a&gt;. &lt;/li&gt;

  &lt;li&gt;While the &lt;a href="https://developer.mozilla.org/en/Mobile/Viewport_meta_tag#Standards" mce_href="https://developer.mozilla.org/en/Mobile/Viewport_meta_tag#Standards"&gt;Viewport Meta Tag isn't an official standard&lt;/a&gt; (yet), it's definitely an industry wide de-facto standard, supported on all modern mobile browsers. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Adaptive styles using CSS Media Queries&lt;/h3&gt;

&lt;p&gt;Okay, we've told browsers that our page will look brilliant when scaled to the current device's screen dimensions. That's a bold claim - how will we follow through on that promise? The answer here is CSS Media Queries.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.w3.org/TR/css3-mediaqueries/" mce_href="http://www.w3.org/TR/css3-mediaqueries/"&gt;CSS Media Queries&lt;/a&gt; allow you to target CSS rules at particular media (display) features. From the W3C spec (er... candidate recommendation):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;HTML4 and CSS2 currently support media-dependent style sheets tailored for different &lt;em&gt;media types&lt;/em&gt;. For example, a document may use sans-serif fonts when displayed on a screen and serif fonts when printed. ‘&lt;code&gt;screen&lt;/code&gt;’ and ‘&lt;code&gt;print&lt;/code&gt;’ are two media types that have been defined. &lt;em&gt;Media queries&lt;/em&gt; extend the functionality of media types by allowing more precise labeling of style sheets. &lt;/p&gt;

  &lt;p&gt;A media query consists of a media type and zero or more expressions that check for the conditions of particular &lt;em&gt;media features&lt;/em&gt;. Among the media features that can be used in media queries are ‘&lt;code&gt;width&lt;/code&gt;’, ‘&lt;code&gt;height&lt;/code&gt;’, and ‘&lt;code&gt;color&lt;/code&gt;’. By using media queries, presentations can be tailored to a specific range of output devices without changing the content itself. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;TL;DR summary: whereas with CSS2 you could use target media types like &lt;em&gt;screen&lt;/em&gt; and &lt;em&gt;print&lt;/em&gt;, with media queries you can target a &lt;em&gt;screen&lt;/em&gt; display with a certain min or max width.&lt;/p&gt;

&lt;p&gt;Remembering that CSS rules are evaluated from top to bottom, this means that we can apply general rules at the top of our CSS file and override them with rules specific to smaller displays later in our CSS, surrounded by a media query so they won't be applied by browsers in larger form-factor displays. &lt;/p&gt;

&lt;p&gt;In the following very simple example, the background will be blue on displays wider than 850px and red on displays narrower than 850px.&lt;/p&gt;

&lt;pre class="brush: css; auto-links: false;"&gt;body {background-color:blue;}
@media only screen and (max-width: 850px) {
    body {background-color:red;}
}&lt;/pre&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;p&gt;That's exactly how the CSS in the default ASP.NET MVC 4 template works: general rules followed by mobile form-factor rules guarded by an 850px max-width media query.&lt;/p&gt;

&lt;p&gt;If you've been paying attention, you'll have guessed that we can test this out just by resizing a desktop browser narrower than 850px, and that guess would be correct:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://farm7.static.flickr.com/6213/6216079899_2c233eaffe_b.jpg" mce_src="http://farm7.static.flickr.com/6213/6216079899_2c233eaffe_b.jpg"&gt;&lt;/p&gt;

&lt;p&gt;If you've got ASP.NET MVC 4 Developer Preview installed (&lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/09/23/asp-net-mvc-4-overview-part-1-installing-asp-net-mvc-4-and-creating-a-new-project.aspx" mce_href="http://weblogs.asp.net/jgalloway/archive/2011/09/23/asp-net-mvc-4-overview-part-1-installing-asp-net-mvc-4-and-creating-a-new-project.aspx"&gt;and I think you should&lt;/a&gt;) you can easily test this out: create a new project, run it, and resize the browser.&lt;/p&gt;

&lt;p&gt;Notes for further study on CSS Media Queries:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you think specs are awesome, you'll love candidate recommendations. Here's the &lt;a href="http://www.w3.org/TR/css3-mediaqueries/" mce_href="http://www.w3.org/TR/css3-mediaqueries/"&gt;W3C Candidate Recommendation for CSS Media Queries&lt;/a&gt;. &lt;/li&gt;

  &lt;li&gt;PPK (over at &lt;a href="http://www.quirksmode.org" mce_href="http://www.quirksmode.org"&gt;quirksmode.org&lt;/a&gt;) has a &lt;a href="http://www.quirksmode.org/blog/archives/2010/09/combining_meta.html" mce_href="http://www.quirksmode.org/blog/archives/2010/09/combining_meta.html"&gt;nice post that ties together Viewports and CSS Media Queries pretty well&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;How does this new template help me create mobile-ready web applications?&lt;/h2&gt;

&lt;p&gt;As I pointed out earlier, the ASP.NET team knows that you'll be largely replacing this design with one that works for your specific application. Hopefully this design is closer to something that you might use, but I'm guessing that your logo will not be "your logo here."&lt;/p&gt;

&lt;p&gt;I see this new design helping in two ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It provides a workable starting point &lt;/li&gt;

  &lt;li&gt;It shows some examples that you can hopefully leverage and extend &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;A workable starting point&lt;/h3&gt;

&lt;p&gt;Starting with a completely empty page when you begin an application wastes your time in many cases. Rather than focusing on the needs of your application, you're stuck with trivia like setting up some standard CSS resets (clearing HTML and body padding, setting some standard float rules, etc.), resetting link styles, picking some halfway decent fonts and looking up the viewport and media query cheat codes you need to scale the page properly. This is a diversion from solving the problem that caused you to hit File/New to begin with.&lt;/p&gt;

&lt;p&gt;Instead, this template will (hopefully) let you get started with a workable design and layout, focus on your business problem, and focus on the design when it makes sense for you.&lt;/p&gt;

&lt;p&gt;If you want to start with an empty slate, you can either use the &lt;strong&gt;Empty&lt;/strong&gt; project template (described in the previous post) to start with a minimal project, or you can quickly delete images and styles that you don't need.&lt;/p&gt;

&lt;h3&gt;Examples&lt;/h3&gt;

&lt;p&gt;This sample layout, while pretty simple, solves a lot of problems developers are forever fighting:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Headers with left and right alignment &lt;/li&gt;

  &lt;li&gt;Handling multiple columns (without resorting to tables or grid systems) &lt;/li&gt;

  &lt;li&gt;Setting style rules that effectively handle differing browser resolutions &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the next time a developer tells me that columns are too hard in HTML and CSS or that it's too much work to set up a layout that adapts to small screen sizes, I'll tell them to open up a new ASP.NET MVC 4 application and take a look.&lt;/p&gt;

&lt;p&gt;That wraps up Part 2 of our ASP.NET MVC 4 overview looking at improvements to the default template for adaptive rendering. In Part 3, we'll take a look at using Display Modes to customize output based on server-side logic.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7983727" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=lDNRaOKBm4k:f8r48DbrRGE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=lDNRaOKBm4k:f8r48DbrRGE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=lDNRaOKBm4k:f8r48DbrRGE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=lDNRaOKBm4k:f8r48DbrRGE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=lDNRaOKBm4k:f8r48DbrRGE:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=lDNRaOKBm4k:f8r48DbrRGE:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=lDNRaOKBm4k:f8r48DbrRGE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/lDNRaOKBm4k" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/jgalloway/archive/tags/Browsers+_2F00_+Web+Development/default.aspx">Browsers / Web Development</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/10/06/asp-net-mvc-4-overview-part-2-default-template-changes-and-adaptive-rendering.aspx</feedburner:origLink></item><item><title>ASP.NET MVC 4 Overview - Part 1: Installing ASP.NET MVC 4 and creating a new project</title><link>http://feedproxy.google.com/~r/jongalloway/~3/XeTTjplBOrQ/asp-net-mvc-4-overview-part-1-installing-asp-net-mvc-4-and-creating-a-new-project.aspx</link><pubDate>Fri, 23 Sep 2011 21:59:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7963023</guid><dc:creator>Jon Galloway</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://weblogs.asp.net/jgalloway/rsscomments.aspx?PostID=7963023</wfw:commentRss><comments>http://weblogs.asp.net/jgalloway/archive/2011/09/23/asp-net-mvc-4-overview-part-1-installing-asp-net-mvc-4-and-creating-a-new-project.aspx#comments</comments><description>&lt;p&gt;I'm starting a series going through some new features in ASP.NET MVC 4. I may accidentally build a working application along the way, for some value of working. Probably not, though. The main goal is to overview what's in ASP.NET MVC 4.&lt;/p&gt;  &lt;p&gt;If you've missed my earlier posts, the top two places to find out what's in ASP.NET MVC 4 are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://asp.net/vnext" mce_href="http://asp.net/vnext"&gt;http://asp.net/vnext&lt;/a&gt; (overview of everything new across the ASP.NET platform)&lt;/li&gt;    &lt;li&gt;&lt;a href="http://asp.net/mvc/mvc4" mce_href="http://asp.net/mvc/mvc4"&gt;http://asp.net/mvc/mvc4&lt;/a&gt; (ASP.NET MVC 4 specific information)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;em&gt;Note: I'll probably go into some obsessive detail about some minor random things in this series. For example, later in this post I dig a bit deeper into the installer than you may care about), so don't read anything into that. Installation on two machines has been really simple for me, but that didn't keep me from digging into some fine points of the installation process.&lt;/em&gt;&lt;/p&gt;  &lt;h2&gt;Background&lt;/h2&gt;  &lt;p&gt;ASP.NET MVC 4 Developer Preview was released at the BUILD conference. It's a Developer Preview, meaning that it's not the official release version and it's &lt;strong&gt;not&lt;/strong&gt;&amp;nbsp;intended for production use. According to the &lt;a href="http://www.asp.net/learn/whitepapers/mvc4-release-notes" mce_href="http://www.asp.net/learn/whitepapers/mvc4-release-notes"&gt;release notes&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;This is a preview release and is not officially supported. If you have questions about working with this release, post them to the ASP.NET MVC forum (&lt;/em&gt;&lt;a href="http://forums.asp.net/1146.aspx" mce_href="http://forums.asp.net/1146.aspx"&gt;&lt;em&gt;http://forums.asp.net/1146.aspx&lt;/em&gt;&lt;/a&gt;&lt;em&gt;), where members of the ASP.NET community are frequently able to provide informal support.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The end user license agreement has more information. Some excerpts from the EULA:&lt;/p&gt;  &lt;ol&gt;   &lt;ol&gt;     &lt;li&gt;       &lt;p&gt;&lt;em&gt;INSTALLATION AND USE RIGHTS &lt;/em&gt;&lt;/p&gt;        &lt;ul&gt;         &lt;li&gt;&lt;em&gt;You may install and use any number of copies of the software on your premises to design, develop and test your ASP.NET programs for use with the software. &lt;/em&gt;&lt;/li&gt;          &lt;li&gt;&lt;em&gt;You may not test the software in a live operating environment unless Microsoft permits you to do so under another agreement. &lt;/em&gt;&lt;/li&gt;       &lt;/ul&gt;     &lt;/li&gt;      &lt;li&gt;&lt;em&gt;TERM. The term of this agreement is until 30/06/2012 (day/month/year), or next release of the software, whichever is first. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;PRE-RELEASE SOFTWARE. This software is a pre-release version. It may not work the way a final version of the software will. We may change it for the final, commercial version. We also may not release a commercial version. &lt;/em&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/ol&gt;  &lt;p&gt;So, kick the tires, report feedback, and get ready for the official release. There's announced release date, but the previous ASP.NET MVC releases have been pretty regular and the expiration term in the EULA seems to fit with that.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ASP.NET MVC 4 Developer Preview runs side by side with previous versions of ASP.NET MVC&lt;/strong&gt;, however there are a few &lt;a href="http://www.asp.net/learn/whitepapers/mvc4-release-notes#_Toc303253815" mce_href="http://www.asp.net/learn/whitepapers/mvc4-release-notes#_Toc303253815"&gt;known issues&lt;/a&gt; to be aware of. The biggest one:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;&lt;strong&gt;Installing ASP.NET MVC 4 Developer Preview breaks ASP.NET MVC 3 RTM applications.&lt;/strong&gt; ASP.NET MVC 3 applications that were created with the RTM release (not with the ASP.NET MVC 3 Tools Update release) require the following changes in order to work side-by-side with ASP.NET MVC 4 Developer Preview. Building the project without making these updates results in compilation errors.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That sounds more scary that it is, since it doesn't apply to the ASP.NET MVC 3 Tools Update (released after the RTM). The readme lists &lt;a href="http://www.asp.net/learn/whitepapers/mvc4-release-notes#_Toc303253815" mce_href="http://www.asp.net/learn/whitepapers/mvc4-release-notes#_Toc303253815"&gt;a pretty quick workaround&lt;/a&gt; for that issue if you do hit it. &lt;/p&gt;  &lt;h2&gt;Installing ASP.NET MVC 4 Developer Preview&lt;/h2&gt;  &lt;p&gt;As with previous releases, you've got two options for installing ASP.NET MVC 4 Developer Previous: Web Platform Installer or manually downloading and running the installer.&lt;/p&gt;  &lt;h3&gt;Option 1: Installing via Web Platform Installer&lt;/h3&gt;  &lt;p&gt;In general, I recommend Web Platform Installer because it checks to make sure you've got the prerequisites; if you're missing something it will figure it out and install it before installing ASP.NET MVC 4. While most developers (myself included) will think they're way too smart for that, a lot of the setup and configuration issues I see (for example, in the MVC Music Store support forum) would have been fixed by using WebPI, and it's caught issues I'd have missed when I've installed it. So my recommendation continues to be to use the Web Platform Installer:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.microsoft.com/web/gallery/install.aspx?appid=MVC4VS2010&amp;amp;prerelease=true" mce_href="http://www.microsoft.com/web/gallery/install.aspx?appid=MVC4VS2010&amp;amp;prerelease=true"&gt;ASP.NET MVC 4 Web Platform Installer for Visual Studio 2010&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/web/gallery/install.aspx?appid=MVC4VS11&amp;amp;prerelease=true" mce_href="http://www.microsoft.com/web/gallery/install.aspx?appid=MVC4VS11&amp;amp;prerelease=true"&gt;ASP.NET MVC 4 Web Platform Installer for Visual Studio 11 Developer Preview&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Option 2: Installing via the installer executable&lt;/h3&gt;  &lt;p&gt;There are a few reasons why you might want to download and run the installer manually:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;In the case of ASP.NET MVC installations, WebPI really just wraps the MVC installer executable. While you're still getting one of the main benefits of WebPI (prerequisite checking), some of the other advantages of WebPI (e.g. &lt;a href="http://weblogs.asp.net/jgalloway/archive/2011/03/17/web-platform-installer-bundles-for-visual-studio-2010-sp1-and-how-you-can-build-your-own-webpi-bundles.aspx" mce_href="http://weblogs.asp.net/jgalloway/archive/2011/03/17/web-platform-installer-bundles-for-visual-studio-2010-sp1-and-how-you-can-build-your-own-webpi-bundles.aspx"&gt;minimizing download and installation time by only getting what you need&lt;/a&gt;) don't apply.&lt;/li&gt;    &lt;li&gt;Since WebPI is wrapping another installer which is updating Visual Studio, if there's an edge case issue with the installer it may not be reported correctly to WebPI. I usually tell people to start with WebPI and in the off chance that they hit a problem, run the installer manually. That way you still get the dependency checking with WebPI.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You can download the ASP.NET MVC 4 installer: &lt;a title="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=27419" href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=27419" mce_href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=27419"&gt;http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=27419&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What gets installed&lt;/p&gt;  &lt;p&gt;The ASP.NET MVC 4 installer looks a lot like the ASP.NET MVC 3 installer:&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-09-09 08h55_07" href="http://www.flickr.com/photos/36836555@N00/6147008053/" mce_href="http://www.flickr.com/photos/36836555@N00/6147008053/"&gt;&lt;img border="0" alt="2011-09-09 08h55_07" src="http://farm7.static.flickr.com/6061/6147008053_9b18e8fd79.jpg" mce_src="http://farm7.static.flickr.com/6061/6147008053_9b18e8fd79.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If you want to watch what it's installing, you can watch the progress information, or you can just crack open the setup file with a compression tool like 7-Zip:&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-09-22 16h25_42" href="http://www.flickr.com/photos/36836555@N00/6173756028/" mce_href="http://www.flickr.com/photos/36836555@N00/6173756028/"&gt;&lt;img border="0" alt="2011-09-22 16h25_42" src="http://farm7.static.flickr.com/6177/6173756028_9db7755c7e_b.jpg" mce_src="http://farm7.static.flickr.com/6177/6173756028_9db7755c7e_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;You can see that the installer includes the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;ASP.NET MVC 4 installer&lt;/strong&gt; (which installs into \Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 4)&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ASP.NET MVC 4 tools&lt;/strong&gt; (for Visual Studio and/or Visual Web Developer, depending on what you've got installed)&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ASP.NET Web Pages 2 installer&lt;/strong&gt; (which installs into \Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v2.0)&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ASP.NET Web Pages tools&lt;/strong&gt; (again, for Visual Studio and/or Visual Web Developer as appropriate)&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;KB2591016 for Visual Studio 2010 SP1&lt;/strong&gt; (I don't know what this is, honestly)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you're really interested, you can unzip the installer and dig around in parameterinfo.xml to see what's installed and under what conditions.&lt;/p&gt;  &lt;p&gt;The installer takes around 15 minutes, the overwhelming majority of which is spent updating VS/VWD tooling. (more on that in a future post when we talk about recipes)&lt;/p&gt;  &lt;h2&gt;File / New Project&lt;/h2&gt;  &lt;p&gt;After installing ASP.NET MVC 4 Developer Preview, you'll see a new project type in the VB and C# / Web sections. I have decided to title my application &lt;a href="http://totl.net/InstantMonkeysOnline/" mce_href="http://totl.net/InstantMonkeysOnline/"&gt;Instant Monkeys Online&lt;/a&gt; as an homage to a venerable Web 1.0 service which has served me well for quite some time, but unfortunately has not been updated to take advantage of modern web technologies.&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-09-23 14h21_49" href="http://www.flickr.com/photos/36836555@N00/6176349744/" mce_href="http://www.flickr.com/photos/36836555@N00/6176349744/"&gt;&lt;img border="0" alt="2011-09-23 14h21_49" src="http://farm7.static.flickr.com/6174/6176349744_944fd93d99_b.jpg" mce_src="http://farm7.static.flickr.com/6174/6176349744_944fd93d99_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After clicking OK (or just pressing the enter key), I get to set a few options about the project I'll be creating.&lt;/p&gt;  &lt;p&gt;&lt;a title="2011-09-23 14h30_49" href="http://www.flickr.com/photos/36836555@N00/6175842061/" mce_href="http://www.flickr.com/photos/36836555@N00/6175842061/"&gt;&lt;img border="0" alt="2011-09-23 14h30_49" src="http://farm7.static.flickr.com/6159/6175842061_220fb7dd43_b.jpg" mce_src="http://farm7.static.flickr.com/6159/6175842061_220fb7dd43_b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If you've been using ASP.NET MVC for a while, you'll notice that the Project Template dialog has been steadily filling up.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Empty&lt;/strong&gt; project template - this stripped down template was added with ASP.NET MVC 2, and is generally intended for developers who want to start from scratch. We actually use this template in the MVC Music Store tutorial so that new developers would start with a clean slate and see how things worked in a new project without any complications or extra "magic."&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Internet Application&lt;/strong&gt; - This is the default template. While it's had some major updates along the what, the Internet Application template is what shipped in ASP.NET MVC 1. It contains a basic design and a login / registration system that interfaces with the ASP.NET membership system. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Intranet Application&lt;/strong&gt; - This shipped with ASP.NET MVC 3. It's very similar to the Internet Application template, but user management is handled via Windows Authentication rather than ASP.NET membership. You can read more about that in the MSDN tutorial: &lt;a href="http://msdn.microsoft.com/en-us/library/gg703322(v=vs.98).aspx" mce_href="http://msdn.microsoft.com/en-us/library/gg703322(v=vs.98).aspx"&gt;How to Create an Intranet Site Using ASP.NET MVC&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Mobile Application&lt;/strong&gt; - This is the new contestant in the project dialog for ASP.NET MVC 4. It creates an application using jQuery Mobile which is specifically intended for mobile browsers. While it will display in a desktop browser, it looks pretty goofy. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For this series, I'm going to go with the Internet Application template. We'll probably look at adding in jQuery Mobile support into this application later.&lt;/p&gt;  &lt;p&gt;That's it for this first installment. We'll take a look at the improvements to the default templates to support adaptive rendering in the next one.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7963023" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=XeTTjplBOrQ:aTfbDzfa0X4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=XeTTjplBOrQ:aTfbDzfa0X4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=XeTTjplBOrQ:aTfbDzfa0X4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=XeTTjplBOrQ:aTfbDzfa0X4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=XeTTjplBOrQ:aTfbDzfa0X4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?i=XeTTjplBOrQ:aTfbDzfa0X4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/jongalloway?a=XeTTjplBOrQ:aTfbDzfa0X4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/jongalloway?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jongalloway/~4/XeTTjplBOrQ" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/jgalloway/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><feedburner:origLink>http://weblogs.asp.net/jgalloway/archive/2011/09/23/asp-net-mvc-4-overview-part-1-installing-asp-net-mvc-4-and-creating-a-new-project.aspx</feedburner:origLink></item><media:rating>nonadult</media:rating></channel></rss>

