<?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:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>SquaredRoot</title>
	
	<link>http://www.squaredroot.com</link>
	<description>.Net Development in DC</description>
	<lastBuildDate>Tue, 16 Jun 2009 04:47:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<geo:lat>38.874979</geo:lat><geo:long>-77.114551</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Squaredroot" type="application/rss+xml" /><item>
		<title>Return of the PagedList</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/GAWKnH0Mum8/</link>
		<comments>http://www.squaredroot.com/2009/06/15/return-of-the-pagedlist/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 10:00:40 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[CodePlex]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[paging]]></category>

		<guid isPermaLink="false">http://www.squaredroot.com/?p=462</guid>
		<description><![CDATA[A few days ago, Craig Stuntz reported an interesting observation: when the first page is returned, the class performs a Skip(0). Suprisingly, this is not free. With that in mind, I set out to correct that issue as well as incorporate a few changes I've made over the past year. The result is nearly identical to the last posted version, just a bit more readable. Additionally...]]></description>
			<content:encoded><![CDATA[<p>It has been nearly a year since I <a href="http://www.squaredroot.com/2008/07/08/PagedList-Strikes-Back/">posted</a> an updated version of the PagedList&lt;T&gt; functionality originally <a href="http://blog.wekeroad.com/blog/aspnet-mvc-pagedlistt">created by Scott Guthrie and posted by Rob Conery</a>. Since then I have used the class in a number of projects and find it indispensable.</p>
<p>A few days ago, Craig Stuntz reported an interesting observation: when the first page is returned, the class performs a Skip(0). Suprisingly, <a href="http://blogs.teamb.com/craigstuntz/2009/06/10/38313/">this is not free</a>. With that in mind, I set out to correct that issue as well as incorporate a few changes I&#8217;ve made over the past year. The result is nearly identical to the last posted version, just a bit more readable. Additionally&#8230;<br />
<span id="more-462"></span></p>
<ul>
<li>The source is now available on CodePlex: <a href="http://pagedlist.codeplex.com">http://pagedlist.codeplex.com</a>. This should make finding and downloading the code easier than finding the correct blog entry on some dude&#8217;s blog.</li>
<li>I have posted a release-compiled, XML commented, signed assembly on CodePlex. I got tired of having to copy the source into multiple projects and finding a place to put it in that project&#8217;s taxonomy.</li>
<li>Further incremental changes can be found in the Change Log on the CodePlex project site.</li>
</ul>
<h3><a href="http://pagedlist.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28585#ReleaseFiles">Download from CodePlex</a></h3>
<p></p>
<h4>IPagedList&lt;T&gt;.cs</h4>
<pre class="brush: csharp">using System.Collections.Generic;

namespace PagedList
{
	public interface IPagedList&lt;T&gt; : IList&lt;T&gt;
	{
		int PageCount { get; }
		int TotalItemCount { get; }
		int PageIndex { get; }
		int PageNumber { get; }
		int PageSize { get; }
		bool HasPreviousPage { get; }
		bool HasNextPage { get; }
		bool IsFirstPage { get; }
		bool IsLastPage { get; }
	}
}</pre>
<h4>PagedList&lt;T&gt;.cs</h4>
<pre class="brush: csharp">using System;
using System.Collections.Generic;
using System.Linq;

namespace PagedList
{
	public class PagedList&lt;T&gt; : List&lt;T&gt;, IPagedList&lt;T&gt;
	{
		public PagedList(IEnumerable&lt;T&gt; superset, int index, int pageSize)
		{
			// set source to blank list if superset is null to prevent exceptions
			var source = superset == null
			                      	? new List&lt;T&gt;().AsQueryable()
									: superset.AsQueryable();

			TotalItemCount = source.Count();
			PageSize = pageSize;
			PageIndex = index;
			if (TotalItemCount &gt; 0)
				PageCount = (int) Math.Ceiling(TotalItemCount/(double) PageSize);
			else
				PageCount = 0;

			if (index &lt; 0)
				throw new ArgumentOutOfRangeException("index", index, "PageIndex cannot be below 0.");
			if (pageSize &lt; 1)
				throw new ArgumentOutOfRangeException("pageSize", pageSize, "PageSize cannot be less than 1.");

			// add items to internal list
			if (TotalItemCount &gt; 0)
				if (index == 0)
					AddRange(source.Take(pageSize).ToList());
				else
					AddRange(source.Skip((index) * pageSize).Take(pageSize).ToList());
		}

		public int PageCount { get; private set; }
		public int TotalItemCount { get; private set; }
		public int PageIndex { get; private set; }
		public int PageSize { get; private set; }

		public int PageNumber
		{
			get { return PageIndex + 1; }
		}

		public bool HasPreviousPage
		{
			get { return PageIndex &gt; 0; }
		}

		public bool HasNextPage
		{
			get { return PageIndex &lt; (PageCount - 1); }
		}

		public bool IsFirstPage
		{
			get { return PageIndex &lt;= 0; }
		}

		public bool IsLastPage
		{
			get { return PageIndex &gt;= (PageCount - 1); }
		}
	}
}</pre>
<h4>PagedListExtensions.cs</h4>
<pre class="brush: csharp">using System.Collections.Generic;
using System.Linq;

namespace PagedList
{
	public static class PagedListExtensions
	{
		public static IPagedList&lt;T&gt; ToPagedList&lt;T&gt;(this IEnumerable&lt;T&gt; superset, int index, int pageSize)
		{
			return new PagedList&lt;T&gt;(superset, index, pageSize);
		}
	}
}</pre>
<h4>PagedListFacts.cs</h4>
<pre class="brush: csharp; collapse: true">using System;
using System.Collections.Generic;
using Xunit;
using Xunit.Extensions;

namespace PagedList.Tests
{
	public class PagedListFacts
	{
		[Fact]
		public void Null_Data_Set_Doesnt_Throw_Exception()
		{
			//act
			Assert.ThrowsDelegate act = () =&gt; new PagedList&lt;object&gt;(null, 0, 10);

			//assert
			Assert.DoesNotThrow(act);
		}

		[Fact]
		public void PageIndex_Below_Zero_Throws_ArgumentOutOfRange()
		{
			//arrange
			var data = new[] {1, 2, 3};

			//act
			Assert.ThrowsDelegate act = () =&gt; data.ToPagedList(-1, 1);

			//assert
			Assert.Throws&lt;ArgumentOutOfRangeException&gt;(act);
		}

		[Fact]
		public void PageIndex_Above_RecordCount_Returns_Empty_List()
		{
			//arrange
			var data = new[] {1, 2, 3};

			//act
			var pagedList = data.ToPagedList(2, 3);

			//assert
			Assert.Equal(0, pagedList.Count);
		}

		[Fact]
		public void PageSize_Below_One_Throws_ArgumentOutOfRange()
		{
			//arrange
			var data = new[] {1, 2, 3};

			//act
			Assert.ThrowsDelegate act = () =&gt; data.ToPagedList(0, 0);

			//assert
			Assert.Throws&lt;ArgumentOutOfRangeException&gt;(act);
		}

		[Fact]
		public void Null_Data_Set_Doesnt_Return_Null()
		{
			//act
			var pagedList = new PagedList&lt;object&gt;(null, 0, 10);

			//assert
			Assert.NotNull(pagedList);
		}

		[Fact]
		public void Null_Data_Set_Returns_Zero_Pages()
		{
			//act
			var pagedList = new PagedList&lt;object&gt;(null, 0, 10);

			//assert
			Assert.Equal(0, pagedList.PageCount);
		}

		[Fact]
		public void Zero_Item_Data_Set_Returns_Zero_Pages()
		{
			//arrange
			var data = new List&lt;object&gt;();

			//act
			var pagedList = data.ToPagedList(0, 10);

			//assert
			Assert.Equal(0, pagedList.PageCount);
		}

		[Fact]
		public void DataSet_Of_One_Through_Five_PageSize_Of_Two_PageIndex_Of_One_First_Item_Is_Three()
		{
			//arrange
			var data = new[] {1, 2, 3, 4, 5};

			//act
			var pagedList = data.ToPagedList(1, 2);

			//assert
			Assert.Equal(3, pagedList[0]);
		}

		[Fact]
		public void TotalCount_Is_Preserved()
		{
			//arrange
			var data = new[] {1, 2, 3, 4, 5};

			//act
			var pagedList = data.ToPagedList(1, 2);

			//assert
			Assert.Equal(5, pagedList.TotalItemCount);
		}

		[Fact]
		public void PageIndex_Is_Preserved()
		{
			//arrange
			var data = new[] {1, 2, 3, 4, 5};

			//act
			var pagedList = data.ToPagedList(1, 2);

			//assert
			Assert.Equal(1, pagedList.PageIndex);
		}

		[Fact]
		public void PageSize_Is_Preserved()
		{
			//arrange
			var data = new[] {1, 2, 3, 4, 5};

			//act
			var pagedList = data.ToPagedList(1, 2);

			//assert
			Assert.Equal(2, pagedList.PageSize);
		}

		[Fact]
		public void Data_Is_Filtered_By_PageSize()
		{
			//arrange
			var data = new[] {1, 2, 3, 4, 5};

			//act
			var pagedList = data.ToPagedList(1, 2);

			//assert
			Assert.Equal(2, pagedList.Count);

			//### related test below

			//act
			pagedList = data.ToPagedList(2, 2);

			//assert
			Assert.Equal(1, pagedList.Count);
		}

		[Fact]
		public void DataSet_OneThroughSix_PageSize_Three_PageIndex_Zero_FirstValue_Is_One()
		{
			//arrange
			var data = new[] { 1, 2, 3, 4, 5, 6 };

			//act
			var pagedList = data.ToPagedList(0, 3);

			//assert
			Assert.Equal(1, pagedList[0]);
		}

		[Fact]
		public void DataSet_OneThroughThree_PageSize_One_PageIndex_Two_HasNextPage_False()
		{
			//arrange
			var data = new[] {1, 2, 3};

			//act
			var pagedList = data.ToPagedList(2, 1);

			//assert
			Assert.Equal(false, pagedList.HasNextPage);
		}

		[Fact]
		public void DataSet_OneThroughThree_PageSize_One_PageIndex_Two_IsLastPage_True()
		{
			//arrange
			var data = new[] {1, 2, 3};

			//act
			var pagedList = data.ToPagedList(2, 1);

			//assert
			Assert.Equal(true, pagedList.IsLastPage);
		}

		[Fact]
		public void DataSet_OneAndTwo_PageSize_One_PageIndex_One_FirstValue_Is_Two()
		{
			//arrange
			var data = new[] { 1, 2 };

			//act
			var pagedList = data.ToPagedList(1, 1);

			//assert
			Assert.Equal(2, pagedList[0]);
		}

		[Theory]
		[InlineData(new[] {1, 2, 3}, 0, 1)]
		[InlineData(new[] {1, 2, 3}, 1, 2)]
		[InlineData(new[] {1, 2, 3}, 2, 3)]
		public void Theory_PageNumber_Is_PageIndex_Plus_One(int[] integers, int pageIndex, int expectedPageNumber)
		{
			//arrange
			var data = integers;

			//act
			var pagedList = data.ToPagedList(pageIndex, 1);

			//assert
			Assert.Equal(expectedPageNumber, pagedList.PageNumber);
		}

		[Theory]
		[InlineData(new[] {1, 2, 3}, 0, 1, false, true)]
		[InlineData(new[] {1, 2, 3}, 1, 1, true, true)]
		[InlineData(new[] {1, 2, 3}, 2, 1, true, false)]
		public void Theory_HasPreviousPage_And_HasNextPage_Are_Correct(int[] integers, int pageIndex, int pageSize,
		                                                               bool expectedHasPrevious, bool expectedHasNext)
		{
			//arrange
			var data = integers;

			//act
			var pagedList = data.ToPagedList(pageIndex, pageSize);

			//assert
			Assert.Equal(expectedHasPrevious, pagedList.HasPreviousPage);
			Assert.Equal(expectedHasNext, pagedList.HasNextPage);
		}

		[Theory]
		[InlineData(new[] {1, 2, 3}, 0, 1, true, false)]
		[InlineData(new[] {1, 2, 3}, 1, 1, false, false)]
		[InlineData(new[] {1, 2, 3}, 2, 1, false, true)]
		public void Theory_IsFirstPage_And_IsLastPage_Are_Correct(int[] integers, int pageIndex, int pageSize,
		                                                          bool expectedIsFirstPage, bool expectedIsLastPage)
		{
			//arrange
			var data = integers;

			//act
			var pagedList = data.ToPagedList(pageIndex, pageSize);

			//assert
			Assert.Equal(expectedIsFirstPage, pagedList.IsFirstPage);
			Assert.Equal(expectedIsLastPage, pagedList.IsLastPage);
		}

		[Theory]
		[InlineData(new[] {1, 2, 3}, 1, 3)]
		[InlineData(new[] {1, 2, 3}, 3, 1)]
		[InlineData(new[] {1}, 1, 1)]
		[InlineData(new[] {1, 2, 3}, 2, 2)]
		[InlineData(new[] {1, 2, 3, 4}, 2, 2)]
		[InlineData(new[] {1, 2, 3, 4, 5}, 2, 3)]
		public void Theory_PageCount_Is_Correct(int[] integers, int pageSize, int expectedNumberOfPages)
		{
			//arrange
			var data = integers;

			//act
			var pagedList = data.ToPagedList(0, pageSize);

			//assert
			Assert.Equal(expectedNumberOfPages, pagedList.PageCount);
		}
	}
}</pre>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2009/06/15/return-of-the-pagedlist/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2009/06/15/return-of-the-pagedlist/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2009/06/15/return-of-the-pagedlist/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2009/06/15/return-of-the-pagedlist/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=GAWKnH0Mum8:qsajjMnFtRo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=GAWKnH0Mum8:qsajjMnFtRo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=GAWKnH0Mum8:qsajjMnFtRo:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/GAWKnH0Mum8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2009/06/15/return-of-the-pagedlist/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2009/06/15/return-of-the-pagedlist/</feedburner:origLink></item>
		<item>
		<title>Creating an MVC Project in Visual Studio 2010</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/YYCNXnunNfU/</link>
		<comments>http://www.squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 22:42:36 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[VS2010]]></category>

		<guid isPermaLink="false">http://www.squaredroot.com/?p=424</guid>
		<description><![CDATA[Earlier today Phil Haack announced that the Asp.Net MVC installer for Visual Studio 2010 Beta 1 is now available on CodePlex along with the bonus of some basic snippets for use with MVC projects. This is exactly what I have been waiting for before installing Visual Studio 2010, so I decided to give it a [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier today <a href="http://www.haacked.com/archive/2009/06/09/aspnetmvc-vs10beta1-roadmap.aspx">Phil Haack announced</a> that the Asp.Net MVC installer for Visual Studio 2010 Beta 1 is <a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527">now available on CodePlex</a> along with the bonus of some basic snippets for use with MVC projects. This is exactly what I have been waiting for before installing Visual Studio 2010, so I decided to give it a shot and report back on my experience. I&#8217;m happy to say that the basic experience went flawlessly for me, though it appears <a href="http://weblogs.asp.net/jacqueseloff/archive/2009/06/09/troubleshooting-the-mvc-installer-for-visual-studio-2010-beta-1.aspx">that may not hold true for everyone</a>.</p>
<p><span id="more-424"></span></p>
<p>The first (and by far the longest) step in getting everything up and running is to download and install the Visual Studio 2010 beta. There are multiple flavors available, but I settled for the plain old Professional edition. You can also choose between the <a href="http://www.microsoft.com/downloadS/details.aspx?familyid=3296BB4F-D8BA-4CFD-AA95-A424C5913F6B&amp;displaylang=en">full install 2 ISO download (1.1 GB)</a> or a <a href="http://www.microsoft.com/downloadS/details.aspx?familyid=75CBCBCD-B0E8-40EA-ADAE-85714E8984E3&amp;displaylang=en">lightweight (5 MB) &#8220;web install&#8221; package</a>. I chose to try out the smaller package and it worked fine for me, though MSDN subscribers with slower connections may prefer to use the Microsoft download tool and download the bigger install so that they can pause and restart the download as needed. Either way, once you&#8217;ve downloaded everything grab a drink and kick off the install. On my relatively fast machine running Windows 7 it took close to half an hour to install and two (!) required restarts.</p>
<p>Once Visual Studio has finished installing, download and install the <a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527">Asp.Net MVC 1.1 Installer for Visual Studio 2010 from CodePlex</a>. While you&#8217;re there, go ahead and download and unzip ASP.NET MVC Snippets for VS2010 Beta 1. While Asp.Net MVC 1.1 is being installed, go ahead and install the snippets as well:</p>
<blockquote><p>Unzip &#8220;ASP.NET MVC Snippets.zip&#8221; into &#8220;C:\Users\&lt;username&gt;\Documents\Visual Studio 10\Code Snippets\Visual Web Developer\My HTML Snippets&#8221;, where &#8220;C:\&#8221; is your OS drive.</p></blockquote>
<p>If you encounter any difficulties with the installer, check out this <a href="http://weblogs.asp.net/jacqueseloff/archive/2009/06/09/troubleshooting-the-mvc-installer-for-visual-studio-2010-beta-1.aspx">blog post by Jacques Eloff</a>. He developed the installer and hopefully his post can help you out. Luckily for me everything proceeded with no problems. Booting up Visual Studio 2010 Beta 1 for the first time, I was presented with the new start screen:</p>
<div id="attachment_433" class="wp-caption alignnone" style="width: 490px"><a href="http://www.squaredroot.com/wp-content/uploads/2009/06/1-vs2010-first-boot.jpg"><img class="size-large wp-image-433" title="Visual Studio 2010 Beta 1 (First Boot)" src="http://www.squaredroot.com/wp-content/uploads/2009/06/1-vs2010-first-boot-1024x736.jpg" alt="The new startup screen of VS2010." width="480" height="345" /></a><p class="wp-caption-text">The new startup screen of VS2010.</p></div>
<div id="attachment_437" class="wp-caption alignright" style="width: 160px"><a href="http://www.squaredroot.com/wp-content/uploads/2009/06/2-creating-mvc-project.jpg"><img class="size-thumbnail wp-image-437" title="Create a New MVC Application" src="http://www.squaredroot.com/wp-content/uploads/2009/06/2-creating-mvc-project-150x150.jpg" alt="The new New Project dialog." width="150" height="150" /></a><p class="wp-caption-text">The new New Project dialog.</p></div>
<p>From here, you can launch the new New Project dialog either via the File menu or by clicking &#8220;Projects&#8221; on the left side of the startup screen and then clicking the &#8220;New Project&#8221; icon. If the Asp.Net MVC 1.1 installer has been correctly installed, you will find a &#8220;ASP.NET MVC Web Application&#8221; entry under the &#8220;Web&#8221; category in the New Project dialog. Fiddle with the Name, Location, and Solution Name as always and then click OK to create your application.</p>
<div id="attachment_438" class="wp-caption alignleft" style="width: 160px"><a href="http://www.squaredroot.com/wp-content/uploads/2009/06/3-create-test-project.jpg"><img class="size-thumbnail wp-image-438" title="Create Test Project Dialog" src="http://www.squaredroot.com/wp-content/uploads/2009/06/3-create-test-project-150x150.jpg" alt="Just click no and setup your own test project using not-MSTest." width="150" height="150" /></a><p class="wp-caption-text">Just click no and setup your own test project using not-MSTest.</p></div>
<p>After clicking OK, we would expect to be presented with the dialog that asks us if we want to create a test project for our new MVC application and indeed it does appear. MSTest is listed by default as always and was the only option available to me even though I do have MBUnit and xUnit.net showing up in this dialog in VS2008. If anyone knows an easy way to get the other test frameworks working with this dialog, please leave a comment or drop me an email. To me this isn&#8217;t a big deal, as I prefer to setup my test projects manually and don&#8217;t see a lot of value in the dialog, but I&#8217;m sure some people prefer to use it. For the sake of expediency I went and ahead and let Visual Studio create an MSTest project (better than nothing, right? maybe?) and proceeded into the project and opened up a view only to hit my next stumbling block&#8230;</p>
<div id="attachment_436" class="wp-caption alignnone" style="width: 490px"><a href="http://www.squaredroot.com/wp-content/uploads/2009/06/4-project-created.jpg"><img class="size-large wp-image-436" title="Created MVC Application But Cant See Anything" src="http://www.squaredroot.com/wp-content/uploads/2009/06/4-project-created-1024x736.jpg" alt="Not entirely legible." width="480" height="344" /></a><p class="wp-caption-text">Not entirely legible.</p></div>
<p>The culprit here is that in Visual Studio 2008 I use a dark theme based off the Vibrant Ink-ish theme <a href="http://blog.wekeroad.com/blog/textmate-theme-for-visual-studio-take-2/">Rob Conery posted a long time ago</a>. Evidently the upgrade process was able to transfer over most of my foreground preferences but none of my background preferences. This left me with light text on a white background. A quick hop skip &amp; a jump through &#8220;Tools&#8221; &gt; &#8220;Import and Export Settings&#8230;&#8221; allowed me to import the defaults, thus making my color scheme readable, if a bit too vanilla.</p>
<p>Now that my application is loaded up and legible, I decided I would make a couple small changes to the application and take some of the old (and new) features for a test drive to see how they did. First I tried out controller scaffolding: right-click on the MVC application&#8217;s Controllers folder and select &#8220;Add &gt; Controller&#8230;&#8221;. That worked fine and was able to generate the CRUD scaffolding I requested. Next I tried automatic view generation: right-click anywhere inside of an action and select &#8220;Add View&#8230;&#8221;. I was pleased to find that neither of these features had been lost and were working as expected.</p>
<div id="attachment_452" class="wp-caption alignright" style="width: 310px"><a href="http://www.squaredroot.com/wp-content/uploads/2009/06/9-choosing-actionlink-snippet.jpg"><img class="size-medium wp-image-452" title="Snippets Dialog" src="http://www.squaredroot.com/wp-content/uploads/2009/06/9-choosing-actionlink-snippet-300x206.jpg" alt="Note to self: delete VB snippets." width="300" height="206" /></a><p class="wp-caption-text">Note to self: delete VB snippets.</p></div>
<p>So now I&#8217;ve created a ProductController with various actions as well as a basic view for the controller&#8217;s Index action, but I don&#8217;t have any way to navigate to that action except typing the URL in by hand. Thinking this might be a good time to try out the new snippets, I opened up the Site.Master view and added a new &lt;li&gt;&lt;/li&gt; to the navigation element. Having not really used snippets much before, I was temporarily lost as I expected to find them in the Toolbox (were they not in there at one point?). Luckily they were even easier to find than that, all I had to do was right-click. <em>(On a side note, this makes it much more likely that I&#8217;ll use them &#8211; the quickest way to get me to not use a Visual Studio feature is to make me deal with the horribly slow loading toolbar).</em> The context-menu inside of views has an &#8220;Insert Snippet&#8230;&#8221; entry that, once selected, will give you three options:  ASP.NET, HTML, and My HTML Snippets. The snippets we installed earlier were placed in our user folder, which means Visual Studio will automatically detect them and load them in to the &#8220;My HTML Snippets&#8221; folder. Selecting that folder presents you with a list of many basic HTML helper snippets.</p>
<p>In this case I wanted to use the first one, actionlink, to create a new call to Html.ActionLink(&#8230;). Selecting it then inserted the Html helper text as I would expect, and highlighted the arguments for the link&#8217;s text and action also as I would expect. I did notice that the snippet doesn&#8217;t automatically insert a placeholder for specifying which controller the actionlink refers to and adding a comma after the last argument did not bring up the list of overloads for Html.ActionLink that I expected to see.</p>
<p>With that done I hit F5 and was able to browse to my Product controller&#8217;s Index action, confirming that Asp.Net MVC is indeed working fine with Visual Studio 2010. It looks like there are still some kinks to work out, but it is already close enough that I feel confident that Beta 2&#8217;s integration should be quite good.</p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=YYCNXnunNfU:9j9E3Ik_CGA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=YYCNXnunNfU:9j9E3Ik_CGA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=YYCNXnunNfU:9j9E3Ik_CGA:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/YYCNXnunNfU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010/</feedburner:origLink></item>
		<item>
		<title>DevPocalypse ? A *Basic* Asp.Net MVC + jQuery Game</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/TXG6gA-GBV0/</link>
		<comments>http://www.squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 11:12:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[codecamp]]></category>

		<guid isPermaLink="false">/post/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample.aspx</guid>
		<description><![CDATA[Last weekend I had the privilege of speaking at the second Northern Virginia CodeCamp of the year, thanks to an invitation from Jeff Schoolcraft. For those of you who were able to make it to the event, thanks for attending, and make sure to fill out an eval! For those of you who didn’t make [...]]]></description>
			<content:encoded><![CDATA[<p>Last weekend I had the privilege of speaking at the second <a href="http://www.novacodecamp.org/">Northern Virginia CodeCamp</a> of the year, thanks to an invitation from <a href="http://thequeue.net/blog/">Jeff Schoolcraft</a>. For those of you who were able to make it to the event, thanks for attending, and make sure to <a href="http://codecampevals.com/">fill out an eval</a>! For those of you who didn’t make it (or those who did and want a deeper peek at the code I presented), feel free to check out the code to my sample app – posted below.</p>
<p><span id="more-6"></span></p>
<h2>DevPocalypse</h2>
<p><strong>ASP.Net MVC + jQuery = Simple Multiplayer Action</strong></p>
<p>The basic idea of the game is that multiple players can exist on a grid (a “screen”) and move around to unoccupied spaces (“blocks”) adjacent to their current location. I had grand hopes of being able to click another player to attack them and include some basic chat, but alas, it was not meant to be. At least not for this presentation. My hope is to continue working on this as a single sample app I can use to illustrate various MVC techniques for future speaking engagements.</p>
<p>Let’s take a gander at what the app looks like when it is running:</p>
<p><a rel="lightview" href="/image.axd?picture=WindowsLiveWriter/DevPocalypseABasicAsp.NetMVCjQueryGame_6351/DevPocalypse-Screenshot_2.jpg"><img style="border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto" title="DevPocalypse-Screenshot" src="/image.axd?picture=WindowsLiveWriter/DevPocalypseABasicAsp.NetMVCjQueryGame_6351/DevPocalypse-Screenshot_thumb.jpg" border="0" alt="DevPocalypse-Screenshot" width="426" height="484" /></a></p>
<p>Yup, like I said: basic. So those two little guys are players. You can’t see it in a screenshot, but when you click a square next to where <em>your</em> player is standing, jQuery will smoothly animate the transition of your character from the current block to the new block. What is even neater is that when a player on a different computer moves <em>their</em> player, you also see the same jQuery animation execute. How are we doing this? Well first we use a simple polling script (from Game.js):</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; line-height: 12pt; background-color: #f4f4f4; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; cursor: text;">
<div style="border-style: none; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   1:</span> $(document).ready(<span style="color: #0000ff">function</span>() {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   2:</span>     updateScreen();</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   3:</span>     setInterval(updateScreen, updateFrequency * 1000);</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   4:</span> });</pre>
</div>
</div>
<p>Ultimately, this code calls an action named GetCurrentScreen on the GameController. Currently this executes twice a second so as to be nice and responsive, but of course I have no idea how that would handle under load. Here is the entire GameController class:</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; line-height: 12pt; background-color: #f4f4f4; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; cursor: text;">
<div style="border-style: none; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   1:</span> <span style="color: #0000ff">using</span> System;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   2:</span> <span style="color: #0000ff">using</span> System.Linq;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   3:</span> <span style="color: #0000ff">using</span> System.Web.Mvc;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   4:</span> <span style="color: #0000ff">using</span> DevPocalypse.Domain;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   5:</span> <span style="color: #0000ff">using</span> DevPocalypse.Domain.Repositories;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   6:</span> <span style="color: #0000ff">using</span> DevPocalypse.Website.App.ModelBinders;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   7:</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   8:</span> <span style="color: #0000ff">namespace</span> DevPocalypse.Website.Controllers</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   9:</span> {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  10:</span>     [Authorize]</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  11:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> GameController : Controller</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  12:</span>     {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  13:</span>         <span style="color: #0000ff">public</span> ICharacterRepository CharacterRepository { get; set; }</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  14:</span>         <span style="color: #0000ff">public</span> IScreenRepository ScreenRepository { get; set; }</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  15:</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  16:</span>         <span style="color: #0000ff">public</span> ViewResult Index()</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  17:</span>         {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  18:</span>             ViewData[<span style="color: #006080">"Title"</span>] = <span style="color: #006080">"Play!"</span>;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  19:</span>             <span style="color: #0000ff">return</span> View();</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  20:</span>         }</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  21:</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  22:</span>         <span style="color: #0000ff">public</span> JsonResult GetCurrentScreen(</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  23:</span>             [ModelBinder( <span style="color: #0000ff">typeof</span>( CurrentCharacterBinder ) )]</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  24:</span>             Character currentCharacter</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  25:</span>             )</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  26:</span>         {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  27:</span>             <span style="color: #008000">// IE will cache aggressively if we don't set our expiration date</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  28:</span>             Response.ExpiresAbsolute = DateTime.Now.AddYears( -1 );</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  29:</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  30:</span>             <span style="color: #008000">// get screen character is on, and a list of all characters on that screen</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  31:</span>             var screen = ScreenRepository.Retrieve().Where( s =&gt; s.ID == currentCharacter.ScreenID ).Single();</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  32:</span>             var characters = CharacterRepository.Retrieve().Where( c =&gt; c.ScreenID == screen.ID ).ToList();</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  33:</span>             <span style="color: #0000ff">return</span> Json( <span style="color: #0000ff">new</span> { Screen = screen, MyCharacter = currentCharacter, Characters = characters } );</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  34:</span>         }</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  35:</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  36:</span>         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> MoveTo(</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  37:</span>             [ModelBinder( <span style="color: #0000ff">typeof</span>( CurrentCharacterBinder ) )]</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  38:</span>             Character currentCharacter,</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  39:</span>             <span style="color: #0000ff">int</span> x,</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  40:</span>             <span style="color: #0000ff">int</span> y</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  41:</span>             )</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  42:</span>         {</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  43:</span>             currentCharacter.X = x;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  44:</span>             currentCharacter.Y = y;</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  45:</span>             CharacterRepository.Update( currentCharacter );</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  46:</span>         }</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  47:</span>     }</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">  48:</span> }</pre>
</div>
</div>
<p>Pretty simple, huh? Note how nice and easy it was to return an anonymous type as a JSON (JavaScript Object Notation) object via the Json(obj) method. Finally, here is the bit of Game.js that performs the actual animation (this is done in a loop updating all characters – hence the <em><strong>id</strong></em> and <em><strong>c</strong></em> variables):</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; line-height: 12pt; background-color: #f4f4f4; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; cursor: text;">
<div style="border-style: none; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   1:</span> $(<span style="color: #006080">"#"</span> + id).animate({</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   2:</span>     left: currentCharacters[c].X * 33,</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: white; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   3:</span>     top: currentCharacters[c].Y * 33</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt;"><span style="color: #606060">   4:</span> }, updateFrequency * 1000 / 4);</pre>
</div>
</div>
<p>Gotta love jQuery. <img src='http://www.squaredroot.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  There is plenty more to look at in the source, so feel free to download it, check it out, play around with it – use it for whatever you want.</p>
<p>Thanks, and I hope to see you at the next CodeCamp!</p>
<p><strong>Download:</strong> <a href="/file.axd?file=2008/12/DevPocalypse.zip">DevPocalypse.zip (762.63 kb)</a></p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=TXG6gA-GBV0:p9pPQHIKTJo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=TXG6gA-GBV0:p9pPQHIKTJo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=TXG6gA-GBV0:p9pPQHIKTJo:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/TXG6gA-GBV0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample/</feedburner:origLink></item>
		<item>
		<title>MVC/jQuery Presentation at NoVa CodeCamp – Dec. 6</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/ge7bOviWDVE/</link>
		<comments>http://www.squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 13:25:24 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[Presentations]]></category>
		<category><![CDATA[codecamp]]></category>

		<guid isPermaLink="false">/post/2008/11/24/MVC-jQuery-Presentation-at-Nova-CodeCamp-December-6-2008.aspx</guid>
		<description><![CDATA[Jeff Schoolcraft was kind enough to ask me to speak at this year’s second NoVa CodeCamp. It is being held in two weeks on Saturday, December 6th at the Microsoft Technology Center in Reston, VA [map]. If you’re interested in attending, please make sure you register soon!
I don’t yet have word on the final presentation [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://novacodecamp.org/"><img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="6a9e34b2-2ad2-440a-8dc1-3accb265b9ca" src="http://www.squaredroot.com/image.axd?picture=WindowsLiveWriter/SpeakingatNoVaCodeCampDec.6_8156/6a9e34b2-2ad2-440a-8dc1-3accb265b9ca_2cab2bb9-23c2-4e0d-b1b6-cb073555af62.jpg" border="0" alt="6a9e34b2-2ad2-440a-8dc1-3accb265b9ca" width="196" height="244" align="right" /></a><a href="http://thequeue.net/blog/">Jeff Schoolcraft</a> was kind enough to ask me to speak at this year’s second <a href="http://novacodecamp.org/">NoVa CodeCamp</a>. It is being held in two weeks on Saturday, December 6th at the Microsoft Technology Center in Reston, VA [<a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;geocode=&amp;q=12012+Sunset+Hills+Rd.++Reston,+VA+20190&amp;sll=37.0625,-95.677068&amp;sspn=51.089971,79.101563&amp;ie=UTF8&amp;z=16&amp;g=12012+Sunset+Hills+Rd.++Reston,+VA+20190&amp;iwloc=addr">map</a>]. If you’re interested in attending, please make sure you <a href="https://www.clicktoattend.com/invitation.aspx?code=131469">register</a> soon!<span id="more-7"></span></p>
<p>I don’t yet have word on the final presentation schedule, but here is the abstract for the presentation I will be giving:</p>
<blockquote><p><strong>Creating an AJAX MMORPG With jQuery &amp; Asp.Net MVC</strong></p>
<p>C&#8217;mon, it&#8217;s Saturday, let&#8217;s take a break from those enterprise class systems and make something that we can enjoy ourselves! Over the past several years users have become increasingly conditioned to expect a fast, responsive UI that communicates changes in a clear manner &#8211; even in the apps we build at our day jobs. We&#8217;ll see how jQuery allows us to build such a UI using AJAX and animations in a quick, cross-platform manner. We&#8217;ll also see how ASP.Net MVC makes it easier than ever to integrate with AJAX frameworks like jQuery. By the end of our session, we&#8217;ll even have a fun little game to play!</p></blockquote>
<p>In the following two weeks I’ll be posting the code I’m currently creating as the basis of this presentation to my blog so that everyone can download it and check it out. I hope to see some of you at the CodeCamp!</p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=ge7bOviWDVE:Bhvo9ZUpzP8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=ge7bOviWDVE:Bhvo9ZUpzP8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=ge7bOviWDVE:Bhvo9ZUpzP8:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/ge7bOviWDVE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008/</feedburner:origLink></item>
		<item>
		<title>My PDC 2008 Agenda</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/UhX1vAqZ36k/</link>
		<comments>http://www.squaredroot.com/2008/10/23/pdc-2008-agenda/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 17:16:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[PDC]]></category>

		<guid isPermaLink="false">/post/2008/10/23/PDC-2008-Agenda.aspx</guid>
		<description><![CDATA[This Saturday I’ll be headed off to sunny Los Angeles for Microsoft’s Professional Developer Conference 2008. This is the first time I’ve gone and I’m really looking forward to it. I’m staying at Hotel Figueroa, only a couple blocks from the Los Angeles Convention Center, and I’ve posted my tentative session agenda (more for my [...]]]></description>
			<content:encoded><![CDATA[<p>This Saturday I’ll be headed off to <a href="http://www.weather.com/weather/tenday/USCA0638?from=36hr_topnav_undeclared">sunny</a> Los Angeles for Microsoft’s <a href="http://microsoftpdc.com">Professional Developer Conference 2008</a>. This is the first time I’ve gone and I’m really looking forward to it. I’m staying at <a href="http://www.figueroahotel.com">Hotel Figueroa</a>, only a couple blocks from the <a href="http://www.lacclink.com">Los Angeles Convention Center</a>, and I’ve posted my tentative session agenda (more for my own reference than anything else) below. If anyone else would like to meet up for drinks after the sessions, <a href="mailto:troygoode@gmail.com">drop me an email</a>.<span id="more-8"></span></p>
<p><strong><span style="text-decoration: underline;">Pre-Conference / Sunday, Oct. 26</span></strong></p>
<ul>
<li><strong>10:00 AM – 5:45 PM</strong><br />
<a href="http://microsoftpdc.com/Agenda/Preconference.aspx#creating-rich-internet-applications-with-silverlight">Creating Rich Internet Applications with Silverlight</a></li>
</ul>
<p><strong><span style="text-decoration: underline;">Day One / Monday, Oct. 27</span></strong></p>
<ul>
<li><strong>8:30 AM – 11:00 AM<br />
</strong><em>Keynote Address</em></li>
<li><strong>11:00 AM – 12:45 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/ES16/">A Lap Around Cloud Services (Part 1)</a></li>
<li><strong>12:45 PM – 1:45 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/PC47/">Microsoft Expression Blend: Tips &amp; Tricks</a></li>
<li><strong>1:45 PM – 3:30 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/PC20/">ASP.Net 4.0 Roadmap</a></li>
<li><strong>3:30 PM – 5:15 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/BB01/">A Lap Around Cloud Services (Part 2)</a> <em>or…<br />
</em><a href="http://channel9.msdn.com/pdc2008/PC21/">ASP.NET MVC: A New Framework for Building Web Applications</a></li>
<li><strong>5:15 PM – 6:30 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/ES01/">Developing and Deploying Your First Cloud Service</a> <em>or…</em><br />
<a href="http://channel9.msdn.com/pdc2008/TL49/">Microsoft .NET Framework: Overview and Applications for Babies</a> <em>or…<br />
</em><a href="http://channel9.msdn.com/pdc2008/TL17/">Windows Workflow Foundation 4.0: A First Look</a></li>
</ul>
<p><strong><span style="text-decoration: underline;">Day Two / Tuesday, Oct. 28</span></strong></p>
<ul>
<li><strong>8:30 AM – 12:45 PM<br />
</strong><em>Keynote Address</em></li>
<li><strong>12:45 PM – 1:45 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/PC24/">Windows 7: Welcome to the Windows 7 Desktop</a></li>
<li><strong>1:45 PM – 3:30 PM<br />
</strong><a href="http://channel9.msdn.com/pdc2008/ES04/">Essential Cloud Storage Services</a></li>
<li><strong>3:30 PM – 5:15 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/PC33/">Microsoft Visual Studio: Easing ASP.NET Web Deployment</a></li>
<li><strong>5:15 PM – 6:30 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/TL20/">Entity Framework Futures</a> <em>or…<br />
</em><a href="http://channel9.msdn.com/pdc2008/PC31/">ASP.NET and JQuery</a> <em>or…<br />
</em><a href="http://channel9.msdn.com/pdc2008/ES02/">Architecting Services for the Cloud</a></li>
</ul>
<p><strong><span style="text-decoration: underline;">Day Three / Wednesday, Oct. 29</span></strong></p>
<ul>
<li><strong>8:30 AM – 10:30 AM<br />
</strong><em>Keynote Address</em></li>
<li><strong>10:30 AM – 12:00 PM<br />
</strong><a href="http://channel9.msdn.com/pdc2008/TL06/">WCF 4.0: Building WCF Services with WF in Microsoft .NET 4.0</a></li>
<li><strong>12:00 PM – 1:15 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/TL43/">Microsoft XNA Game Studio: An Overview</a></li>
<li><strong>1:15 PM – 3:00 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/TL18/">&#8220;Oslo&#8221;: Customizing and Extending the Visual Design Experience</a></li>
<li><strong>3:00 PM – 4:45 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/ES03/">A Day in the Life of a Cloud Service Developer</a> <em>or…<br />
</em><a href="http://channel9.msdn.com/pdc2008/PC55/">Oomph: A Microformat Toolkit</a> <em>or…<br />
</em><a href="http://channel9.msdn.com/pdc2008/TL28/">&#8220;Oslo&#8221;: Repository and Models</a></li>
<li><strong>4:45 PM – 6:00 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/TL23-R/">A Lap around &#8220;Oslo&#8221;</a></li>
</ul>
<p><strong><span style="text-decoration: underline;">Day Four / Thursday, Oct. 30</span></strong></p>
<ul>
<li><strong>8:30 AM – 10:15 AM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/TL04/">WCF: Developing RESTful Services</a></li>
<li><strong>10:15 AM – 12:00 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/SYMP05/">Services Symposium: Enterprise Grade Cloud Applications</a></li>
<li><strong>12:00 PM – 1:45 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/ES17/">Cloud Computing: Programming in the Cloud</a></li>
<li><strong>1:45 PM – 3:00 PM</strong><br />
<a href="http://channel9.msdn.com/pdc2008/PC32/">ASP.NET AJAX Futures</a> <em>or…<br />
</em><a href="http://channel9.msdn.com/pdc2008/BB27/">Workflow Services: Orchestrating Services and Business Processes Using Cloud-Based Workflow</a></li>
</ul>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/10/23/pdc-2008-agenda/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/10/23/pdc-2008-agenda/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/10/23/pdc-2008-agenda/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/10/23/pdc-2008-agenda/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=UhX1vAqZ36k:gLB0YHEuJSQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=UhX1vAqZ36k:gLB0YHEuJSQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=UhX1vAqZ36k:gLB0YHEuJSQ:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/UhX1vAqZ36k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/10/23/pdc-2008-agenda/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2008/10/23/pdc-2008-agenda/</feedburner:origLink></item>
		<item>
		<title>ASP.Net MVC Goes Beta!</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/KqW8V1U3ATQ/</link>
		<comments>http://www.squaredroot.com/2008/10/16/aspnet-mvc-beta-release/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 21:49:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">/post/2008/10/16/aspnet-mvc-beta-release.aspx</guid>
		<description><![CDATA[I discovered via DotNetKicks this afternoon that the ASP.Net MVC framework’s beta release is now available for download from Microsoft.com. No release or source code is yet available from the CodePlex project, but I expect we’ll see it there soon enough. Congratulations to the team at Microsoft, RTM is knocking at the door!
Download ASP.Net MVC [...]]]></description>
			<content:encoded><![CDATA[<p>I discovered via <a href="http://www.dotnetkicks.com/aspnet/ASP_net_MVC_goes_Beta">DotNetKicks</a> this afternoon that the ASP.Net MVC framework’s beta release is now <a href="http://www.microsoft.com/downloads/details.aspx?familyid=a24d1e00-cd35-4f66-baa0-2362bdde0766&amp;displaylang=en&amp;tm">available for download from Microsoft.com</a>. No release or source code is yet available from the <a href="http://www.codeplex.com/aspnet">CodePlex project</a>, but I expect we’ll see it there soon enough. Congratulations to the team at Microsoft, RTM is knocking at the door!</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?familyid=a24d1e00-cd35-4f66-baa0-2362bdde0766&amp;displaylang=en&amp;tm"><strong>Download ASP.Net MVC Beta</strong></a></p>
<p>For those who, like me, have been following along with each preview push at the CodePlex project, I found a list of changes made between Preview 5 and Beta buried at the bottom of the Release Notes document. Here they are in their entirety:<span id="more-9"></span></p>
<blockquote><p><strong>Changes Made Between CodePlex Preview 5 and Beta</strong></p>
<p>Even though the last official release of ASP.NET MVC was ASP.NET MVC Preview 3, many developers downloaded and used the interim CodePlex releases. This section describes changes and bug fixes that have been made between CodePlex Preview 5 and Beta.</p>
<p><strong>Changes</strong></p>
<ul>
<li>Changed the default validation messages to be more end-user friendly.</li>
<li>Renamed <em>CompositeViewEngine</em> to <em>AutoViewEngine</em>.</li>
<li>Added a <em>Url</em> property to <em>Controller</em> of type <em>UrlHelper</em>. This makes it convenient to generate routing-based URLs from within a controller.</li>
<li>Added the <em>ActionNameSelectorAttribute</em> abstract base class, which serves as the base type for <em>ActionNameAttribute</em>. By inheriting from this base attribute class, you can create custom attributes that participate in action selection by name.</li>
<li>Added a new <em>ReleaseView</em> method to <em>IViewEngine</em> that allows custom view engines to be notified when a view is done rendering. This is useful for cleanup or for view-pooling scenarios.</li>
<li>Renamed the <em>ControllerBuilder</em> method <em>DisposeController</em> to <em>ReleaseController</em> to fit with the pattern that is established for view engines.</li>
<li>Removed most of the methods on the <em>HtmlHelper</em> class, converting them to extension methods of the <em>HtmlHelper</em> class instead. These methods exist in a new namespace (<em>System.Web.Mvc.Html</em>). If you are migrating from Preview 5, you must add the following element to the namespaces section of the Web.config file:<em>&lt;add namespace=&#8221;System.Web.Mvc.Html&#8221;/&gt;</em>
<p>This makes it possible for you to completely replace our helper methods with your own.</li>
<li>Changed the default model binder (<em>DefaultModelBinder</em>) to handle complex types. The <em>IModelBinder</em> interface has also been changed to accept a single parameter of type <em>ModelBindingContext</em>.</li>
<li>Added a new <em>HttpVerbs</em> enumeration that contains the most commonly used HTTP verbs (GET, POST, PUT, DELETE, HEAD). Also added a constructor overload to <em>AcceptVerbsAttribute</em> that accepts the enumeration. The enumerated values can be combined. For example, the following snippet shows an action method that can respond to both POST and PUT requests.<em>[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Put)]<br />
public ActionResult Update() {<br />
}</em></p>
<p>Because it is possible to respond to HTTP verbs that are not included in the enumeration, the <em>AcceptVerbsAttribute</em> retains the constructor that accepts an array of strings as a parameter.</li>
<li>Modified the <em>RadioButton</em> helper method to ensure that every overload accepts a value. Because radio buttons are used to specify a choice from a set of possible values, specifying a value for a radio button is necessary.</li>
<li>Made modifications and fixes to the default project template. This includes moving script files to a new Scripts folder. The default template uses the <em>ModelState</em> class to report validation errors.</li>
<li>Changed action-method selection. If two action methods match a request, but only one of those has an attribute that derives from <em>ActionMethodSelectorAttribute</em> that matches the request, that action is invoked. In earlier releases, this scenario resulted in an exception.For example, the following two action methods are in the same controller:
<p><em>public ActionResult Edit() {<br />
//&#8230;<br />
} [AcceptVerbs(HttpVerbs.Post)] </em></p>
<p><em> </em><em> public ActionResult Edit(FormCollection form) {<br />
//&#8230;<br />
}</em></p>
<p>In Preview 5, a POST request for the <em>Edit</em> action would cause an exception, because two methods match the request. In the Beta, precedence is given to the method that matches the current request via the <em>AcceptVerb</em> attribute. In this example, the first method will handle any non-POST requests for the <em>Edit</em> action.</li>
<li>Added an overload for the <em>ViewDataDictionary.Eval</em> method that accepts a format string.</li>
<li>Removed the <em>ViewName</em> property from the <em>ViewContext</em> class.</li>
<li>Added an <em>IValueProvider</em> interface for value providers, along with a default implementation, <em>DefaultValueProvider</em>. Value providers supply values that are used by the model binders when binding to a model object. The <em>UpdateModel</em> method of the <em>Controller</em> class has been updated to allow you to specify a custom value provider.</li>
</ul>
<p><strong>Bug Fixes</strong></p>
<ul>
<li>Fixed a bug in which the ignore-routes setting (created by using the <em>IgnoreRoute</em> extension method) affected URL generation.</li>
<li>Fixed a view engine caching bug when the application is not in debug mode (that is, when <em>debug=&#8221;false&#8221;</em> is set in the Web.config file). This bug occurred if different action methods in different controllers had the same name. In that case, an action method could render the view for the wrong controller.</li>
<li>Fixed a bug in <em>OutputCacheAttribute</em> in which cached authenticated content did not require authentication. Even though the content is cached, if it requires authentication, the user should be required to authenticate first before seeing the cached content.</li>
<li>Fixed a bug in which <em>RenderPartial</em> does not work when tracing is turned on.</li>
<li>Fixed a bug in the <em>Html.TextArea</em> helper method in which an overload was not looking in <em>ViewData</em> for its value when the provided value is null.</li>
<li>Fixed the <em>OutputCacheAttribute.CacheProfile</em> property so that it works in Medium Trust.</li>
</ul>
<p><strong>Upgrading from CodePlex Preview 5 to Beta</strong></p>
<p>There are not many changes between ASP.NET MVC Preview 5 and Beta. However, you will need to make a few changes to your applications after you install the Beta release. Most of these changes are apparent when you try to compile your application by using the latest binaries, so we do not list every possible change. The compiler will guide you there. The following list describes some of the changes that you must make.</p>
<ul>
<li>Update the references to the following assemblies to point to the new Beta versions of the assemblies:<em>System.Web.Abstractions.dll<br />
System.Web.Routing.dll<br />
System.Web.Mvc.dll</em></p>
<p>By default, these assemblies are located in the following folder:</p>
<p><em>%ProgramFiles%Microsoft ASP.NETASP.NET MVC Beta</em></li>
<li>In the Web.config namespaces section, add the following namespace entry if it is not there already:<em>&lt;add namespace=&#8221;System.Web.Mvc.Html&#8221;/&gt;</em></li>
<li>The Form HTML helper was renamed to <em>BeginForm</em>.</li>
<li>After you have made these changes, compile your application and resolve any compilation errors. Most of the errors will be the result of one of the breaking changes listed earlier.</li>
</ul>
</blockquote>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/10/16/aspnet-mvc-beta-release/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/10/16/aspnet-mvc-beta-release/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/10/16/aspnet-mvc-beta-release/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/10/16/aspnet-mvc-beta-release/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=KqW8V1U3ATQ:F892G85osGY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=KqW8V1U3ATQ:F892G85osGY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=KqW8V1U3ATQ:F892G85osGY:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/KqW8V1U3ATQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/10/16/aspnet-mvc-beta-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2008/10/16/aspnet-mvc-beta-release/</feedburner:origLink></item>
		<item>
		<title>Introduction to ASP.Net MVC for Alt.Net DC – Presentation Materials</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/xv2XYy_8UvA/</link>
		<comments>http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 02:44:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Alt.net]]></category>

		<guid isPermaLink="false">/post/2008/09/24/AltDotNet-Presentation-20080924-Materials.aspx</guid>
		<description><![CDATA[I just got back from my ASP.Net MVC Presentation for tonight’s DC Alt.Net meeting and I had a great time. I hope everyone got a good feel for what it takes to develop an application using the MVC framework. Please don’t hesitate to contact me if you have any questions. Also I owe a big [...]]]></description>
			<content:encoded><![CDATA[<p>I just got back from my ASP.Net MVC Presentation for tonight’s DC Alt.Net meeting and I had a great time. I hope everyone got a good feel for what it takes to develop an application using the MVC framework. Please don’t hesitate to <a href="/page/About-Me.aspx#ContactInformation">contact me</a> if you have any questions. Also I owe a big thanks to <a href="http://codebetter.com/blogs/matthew.podwysocki/default.aspx">Matthew Podwysocki</a> for inviting me to speak. Thanks Matt, I really enjoyed the opportunity.</p>
<p>I promised that I would post the project that we created tonight (a basic blog engine), which you can now find linked below. There are three projects in the solution:<span id="more-10"></span></p>
<ol>
<li><strong>MvcTutorials.Blog.Domain<br />
</strong>This project has the Comment &amp; Post entities, as well as the repositories used to populate them.</li>
<li><strong>MvcTutorials.Blog.Domain.Bootstrap<br />
</strong>This project adds random data to the blog database for testing.</li>
<li><strong>MvcTutorials.Blog.ReferenceWebsite<br />
</strong>This is the MVC website I created prior to the meeting to decide what I was going to present and how long it would take to do it. This is where you’ll find the code we wrote tonight.</li>
</ol>
<p>If you want to run the project, make sure you have SQL Server Express installed and create a database named “MvcTutorial-Blog”. Afterward you can run the “MvcTutorials.Blog.Domain.Bootstrap” project to insert test data and run the website project.</p>
<p>Be sure to let me know if there are any questions or comments about tonight’s presentation or this post’s code!</p>
<p><strong>Presentation Materials:</strong><br />
<a href="/file.axd?file=2008%2f9%2fMvcTutorial-Blog.zip">MvcTutorial-Blog.zip (307.06 kb)</a></p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=xv2XYy_8UvA:vjddXtC1ilU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=xv2XYy_8UvA:vjddXtC1ilU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=xv2XYy_8UvA:vjddXtC1ilU:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/xv2XYy_8UvA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials/</feedburner:origLink></item>
		<item>
		<title>Introduction to ASP.Net MVC for Alt.Net DC Tonight</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/idfElKs7fGk/</link>
		<comments>http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 19:53:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Alt.net]]></category>

		<guid isPermaLink="false">/post/2008/09/24/AltDotNet-Presentation-20080924.aspx</guid>
		<description><![CDATA[
Anyone in the Washington, DC area who is interested in an introductory peek at Microsoft&#8217;s new ASP.Net MVC platform is invited to come out to tonight&#8217;s Alt.Net meeting. I will be presenting the front-to-back basics you need to know to get started in developing with the MVC framework, using a MVC blog engine as our [...]]]></description>
			<content:encoded><![CDATA[<p>
Anyone in the Washington, DC area who is interested in an introductory peek at Microsoft&rsquo;s new ASP.Net MVC platform is invited to come out to tonight&rsquo;s Alt.Net meeting. I will be presenting the front-to-back basics you need to know to get started in developing with the MVC framework, using a MVC blog engine as our use case. Details about the when/where below. Many thanks to Matthew Podwysocki for asking me to speak tonight; it is a great privilege.
</p>
<p>
<strong>When:</strong>
</p>
<p>
September 24, 2008 &#8211; 7PM to 9PM
</p>
<p>
<strong>Where:</strong>
</p>
<p>
<a href="http://www.cynergysystems.com/">Cynergy Systems Inc.</a>     <br />
1600 K St NW     <br />
Suite 300     <br />
Washington, DC 20006     <br />
<a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;geocode=&amp;q=1600+K+St+NW,+Washington,+DC+20006&amp;sll=38.880459,-77.109452&amp;sspn=0.012444,0.027895&amp;ie=UTF8&amp;z=16">GoogleMaps</a>
</p>
<p>
<strong>More Info:</strong>
</p>
<p>
<a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2008/09/08/dc-alt-net-9-24-2008-building-asp-net-mvc-applications-with-troy-goode.aspx" title="http://codebetter.com/blogs/matthew.podwysocki/archive/2008/09/08/dc-alt-net-9-24-2008-building-asp-net-mvc-applications-with-troy-goode.aspx">Matthew Podwysocki&#39;s Blog Post</a></p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=idfElKs7fGk:UoJ1I1EaIJQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=idfElKs7fGk:UoJ1I1EaIJQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=idfElKs7fGk:UoJ1I1EaIJQ:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/idfElKs7fGk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2008/09/24/altdotnet-presentation-20080924/</feedburner:origLink></item>
		<item>
		<title>MVC Membership – Preview 5</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/B9QPRrCVkvU/</link>
		<comments>http://www.squaredroot.com/2008/09/06/mvc-membership-preview-5/#comments</comments>
		<pubDate>Sat, 06 Sep 2008 13:15:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[membership]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">/post/2008/09/06/MVC-Membership-Preview-5.aspx</guid>
		<description><![CDATA[Last weekend I posted a release of the MVC Membership Starter Kit that targets Preview 5 of the ASP.Net MVC framework. There was no packaged release targeting Preview 4 (though if you downloaded the latest source, it worked), so this release essentially packages the changes from both previews.
Why does the MVC Membership Starter Kit still [...]]]></description>
			<content:encoded><![CDATA[<p>Last weekend I posted a release of the MVC Membership Starter Kit that targets <a href="http://haacked.com/archive/2008/08/29/asp.net-mvc-codeplex-preview-5-released.aspx">Preview 5 of the ASP.Net MVC framework</a>. There was no packaged release targeting <a href="http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx">Preview 4</a> (though if you <a href="http://www.codeplex.com/MvcMembership/SourceControl/ListDownloadableCommits.aspx">downloaded the latest source</a>, it worked), so this release essentially packages the changes from both previews.<span id="more-12"></span></p>
<h2>Why does the MVC Membership Starter Kit still exist?</h2>
<p>The biggest change affecting the MVC Membership Starter Kit is that the default ASP.Net MVC Web Application project includes <a href="http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx">login/logout, register, and change password functionality as of Preview 4</a>. This is great and I’m glad to see them do it. It is my hope they will eventually include membership administration functionality as well. For now, however, they haven’t included it. This leaves three main features that are now driving the existence of this project:</p>
<ol>
<li><strong>Membership Administration</strong><br />
What good is registration, login, and logout if a site’s owner cannot change a user’s roles or manage their user base? While Visual Studio’s <a href="http://msdn.microsoft.com/en-us/library/yy40ytx0.aspx">Web Site Administration Tool</a> covers most of your bases during development, it isn’t a real option for use by web site administrators in a production application.</li>
<li><strong>OpenID Integration</strong><br />
Preview 4’s built-in login functionality only covers the use of standard username/password authentication. It seems likely that this will continue, as I am not aware of any plans for official <a href="http://openid.net/">OpenID</a> support within the .Net framework. We are using <a href="http://code.google.com/p/dotnetopenid/">Andrew Arnott &amp; co’s DotNetOpenId</a> project to help you let your users log in using OpenID.</li>
<li><strong>WindowsLive LiveID Integration</strong><br />
<a href="http://blog.maartenballiauw.be/">Maarten</a>’s <a href="http://dev.live.com/liveid/">LiveID</a> integration has unfortunately not made this release. I anticipate that it will be available again for the next release, which will target <a href="http://haacked.com/archive/2008/09/05/mvcfutures-and-asp.net-mvc-beta.aspx">the first beta release of ASP.Net MVC</a>.</li>
</ol>
<h2>What has changed?</h2>
<ol>
<li><strong>No more login/logout/password retrieval.</strong><br />
Because the AccountController and its views are now included by default in new projects, the need for this functionality has gone away.</li>
<li><strong>Less assemblies to reference.</strong><br />
Rather than the MembershipAdministrationController and other code being compiled into a separate assembly that you must include, you now drop the controllers directly into your web app. This allows you to easily change the code as your project evolves. The starter kit’s implementation is really just a starting point that you can build off of.</li>
<li><strong>Controllers are split.</strong><br />
In previous releases the OpenID and WindowsLive login functionality was included in the MembershipAuthenticationController. The OpenID functionality has since been moved into a separate controller with separate views. This was done because (a) the MembershipAuthenticationController no longer exists and (b) moving forward more of the pieces of this kit will be separated from each other so that you can include them a la carte.</li>
</ol>
<h2>Download</h2>
<p>You can download the Preview 5 release of the MVC Membership Starter Kit from CodePlex:</p>
<p><a title="http://www.codeplex.com/MvcMembership/Release/ProjectReleases.aspx?ReleaseId=16809#ReleaseFiles" href="http://www.codeplex.com/MvcMembership/Release/ProjectReleases.aspx?ReleaseId=16809#ReleaseFiles">http://www.codeplex.com/MvcMembership…?ReleaseId=16809</a></p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/09/06/mvc-membership-preview-5/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/09/06/mvc-membership-preview-5/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/09/06/mvc-membership-preview-5/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/09/06/mvc-membership-preview-5/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=B9QPRrCVkvU:P5Y3W56ia5M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=B9QPRrCVkvU:P5Y3W56ia5M:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=B9QPRrCVkvU:P5Y3W56ia5M:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/B9QPRrCVkvU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/09/06/mvc-membership-preview-5/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2008/09/06/mvc-membership-preview-5/</feedburner:origLink></item>
		<item>
		<title>MVC Controller Action Security Hole</title>
		<link>http://feedproxy.google.com/~r/Squaredroot/~3/1-GzLCoZvk8/</link>
		<comments>http://www.squaredroot.com/2008/07/08/mvc-controller-action-security-hole/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 22:14:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">/post/2008/07/08/MVC-Controller-Action-Security-Hole.aspx</guid>
		<description><![CDATA[The latest of Stephen Walther&#8217;s invaluable ASP.Net MVC Tip series points out a MVC scenario that was previously unknown to me: passing cookies and server variables into controllers as action parameters. While the idea is neat, a comment left by Francois Ward echoed my immediate skepticism over whether this could be safe. After playing around [...]]]></description>
			<content:encoded><![CDATA[<p>The latest of <a href="http://weblogs.asp.net/stephenwalther/">Stephen Walther</a>&#8217;s invaluable <a href="http://weblogs.asp.net/stephenwalther/archive/tags/Tips/default.aspx">ASP.Net MVC Tip series</a> points out a MVC scenario that was previously unknown to me: <a href="http://weblogs.asp.net/stephenwalther/archive/2008/07/08/asp-net-mvc-tip-15-pass-browser-cookies-and-server-variables-as-action-parameters.aspx">passing cookies and server variables into controllers as action parameters</a>. While the idea is neat, <a href="http://weblogs.asp.net/stephenwalther/archive/2008/07/08/asp-net-mvc-tip-15-pass-browser-cookies-and-server-variables-as-action-parameters.aspx#6377484">a comment left by Francois Ward</a> echoed my immediate skepticism over whether this could be safe. After playing around I believe I have confirmed my suspicions that making use of this capability is a Very Bad Idea.<span id="more-13"></span></p>
<p>I&#8217;ll let Francois&#8217; comment explain the problem (emphasis mine):</p>
<blockquote><p>Tuesday, July 08, 2008 4:16 PM by Francois Ward</p>
<p>Hmm, I didn&#8217;t look into it much, but is that -safe-? I mean, if the variables in the index function are filled up automatically&#8230; it would be ok if it was only one type (all cookies, or all server variables), but since you can mix and match, <strong>whats to present me from forging a request with a cookie with the same name as the server variables</strong>?</p>
<p>I mean, it is already possible to forge anything client-related, for obvious reason&#8230; but <strong>forging info that potentially come from the server</strong>? That seems&#8230;awkward&#8230;</p>
<p>(again, keep in mind this is just my first reaction, maybe if I think it through I&#8217;ll realise what I just said is totally stupid <img src='http://www.squaredroot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p></blockquote>
<p>Like Francois said, cookies are easily forged client-side anyway, but most developers tend to rely on the <a href="http://en.wikipedia.org/wiki/Truthiness">truthiness</a> of our server variables, specifically those that don&#8217;t come over in the HTTP request. Let me demonstrate how the issue plays out.</p>
<p>For our example I have created a method on the HomeController named Test that takes four parameters that match server variable names. Below are the descriptions of each from MSDN&#8217;s <a href="http://msdn.microsoft.com/en-us/library/ms524602.aspx">IIS Server Variables</a> article:</p>
<ul>
<li><strong>REMOTE_ADDR<br />
</strong>MSDN Says, &#8220;The IP address of the remote host that is making the request.&#8221;</li>
<li><strong>LOGON_USER</strong><br />
MSDN Says, &#8220;The Windows account that the user is impersonating while connected to your Web server. Use REMOTE_USER, UNMAPPED_REMOTE_USER, or AUTH_USER to view the raw user name that is contained in the request header. The only time LOGON_USER holds a different value than these other variables is if you have an authentication filter installed.&#8221;</li>
<li><strong>REQUEST_METHOD</strong><br />
MSDN Says, &#8220;The method used to make the request. For HTTP, this can be <strong>GET</strong>, <strong>HEAD</strong>, <strong>POST</strong>, and so on.&#8221;</li>
<li><strong>SERVER_NAME</strong><br />
The server&#8217;s host name, DNS alias, or IP address as it would appear in self-referencing URLs.</li>
</ul>
<p>My biggest concern is <strong>LOGON_USER</strong>. As described by MSDN this variable normally stores whatever the value of REMOTE_USER, UNMAPPED_REMOTE_USER, or AUTH_USER is, except when you have a third party authentication filter installed. The purpose of these authentication filters is to map the value of one of the above three request variables to a different local name. For example, you may be using a filter to map &#8220;DOMAINTroyGoode&#8221; to &#8220;DOMAIN-DMZStandardUser&#8221; and to map &#8220;DOMAINScottGuthrie&#8221; to &#8220;DOMAIN-DMZAdministrator&#8221;. If you are using such a filter and then add LOGON_USER as a parameter to one of your actions, you are suddenly opening up the ability for anyone to circumvent that authentication filter.</p>
<p>Here is the action I have created:</p>
<div class="csharpcode-wrapper">
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">public</span> <span class="kwrd">void</span> Test(   <span class="kwrd">string</span> REMOTE_ADDR,</pre>
<pre class="alteven"><span class="lnum">   2:</span>                     <span class="kwrd">string</span> LOGON_USER,</pre>
<pre class="alt"><span class="lnum">   3:</span>                     <span class="kwrd">string</span> REQUEST_METHOD,</pre>
<pre class="alteven"><span class="lnum">   4:</span>                     <span class="kwrd">string</span> SERVER_NAME )</pre>
<pre class="alt"><span class="lnum">   5:</span> {</pre>
<pre class="alteven"><span class="lnum">   6:</span>     Response.Write(</pre>
<pre class="alt"><span class="lnum">   7:</span>         <span class="kwrd">string</span>.Format(  <span class="str">"&lt;div&gt;Remote IP: {0}&lt;/div&gt;"</span> +</pre>
<pre class="alteven"><span class="lnum">   8:</span>                         <span class="str">"&lt;div&gt;User: {1}&lt;/div&gt;"</span> +</pre>
<pre class="alt"><span class="lnum">   9:</span>                         <span class="str">"&lt;div&gt;Request Method: {2}&lt;/div&gt;"</span> +</pre>
<pre class="alteven"><span class="lnum">  10:</span>                         <span class="str">"&lt;div&gt;Server Name: {3}&lt;/div&gt;"</span>,</pre>
<pre class="alt"><span class="lnum">  11:</span>             REMOTE_ADDR,</pre>
<pre class="alteven"><span class="lnum">  12:</span>             LOGON_USER,</pre>
<pre class="alt"><span class="lnum">  13:</span>             REQUEST_METHOD,</pre>
<pre class="alteven"><span class="lnum">  14:</span>             SERVER_NAME</pre>
<pre class="alt"><span class="lnum">  15:</span>         )</pre>
<pre class="alteven"><span class="lnum">  16:</span>     );</pre>
<pre class="alt"><span class="lnum">  17:</span> }</pre>
</div>
</div>
<p>And here is what this action will output without any fiddling:</p>
<p><a href="/image.axd?picture=WindowsLiveWriter/MVCRoutingSecurityHole_F8B7/Unhacked_2.jpg"><img style="border-width: 0px" src="/image.axd?picture=WindowsLiveWriter/MVCRoutingSecurityHole_F8B7/Unhacked_thumb.jpg" border="0" alt="Unhacked" width="462" height="145" /></a></p>
<p>Now I&#8217;ll tweak the Url a bit:</p>
<blockquote><p>First Url:</p>
<p><a title="http://localhost:63260/Home/Test" href="http://localhost:63260/Home/Test">http://localhost:63260/Home/Test</a></p>
<p>Second Url:</p>
<p><a title="http://localhost:63260/Home/Test?REMOTE_ADDR=Any.IP.I.Want&amp;LOGON_USER=YourDomainAdministrator&amp;REQUEST_METHOD=POST&amp;SERVER_NAME=microsoft.com" href="http://localhost:63260/Home/Test?REMOTE_ADDR=Any.IP.I.Want&amp;LOGON_USER=YourDomainAdministrator&amp;REQUEST_METHOD=POST&amp;SERVER_NAME=microsoft.com">http://localhost:63260/Home/Test?REMOTE_ADDR=Any.IP.I.Want&amp;LOGON_USER=YourDomainAdministrator&amp;REQUEST_METHOD=POST&amp;SERVER_NAME=microsoft.com</a></p></blockquote>
<p>And voilà, mischief achieved:</p>
<p><a href="/image.axd?picture=WindowsLiveWriter/MVCRoutingSecurityHole_F8B7/TotallyHaxxored_2.jpg"><img style="border-width: 0px" src="/image.axd?picture=WindowsLiveWriter/MVCRoutingSecurityHole_F8B7/TotallyHaxxored_thumb.jpg" border="0" alt="Totally Haxxored" width="462" height="145" /></a></p>
<p>Now I&#8217;m no Kevin Mitnick, but I can assure you that if I can come up with something like this in an hour or so, a dedicated hacker that is probably far smarter than I will likely give you a lot of heartache if you make use of this feature. Have any &#8220;developer mode checks&#8221; that check for 127.0.0.1 or localhost? Have any filters to try and prevent GETs on certain actions? Relying on server variables passed in to your actions would make those scenarios (and many others) unwise.  Just say no.</p>
<p>In my opinion this feature (the server variable portion) should just be removed from the MVC framework entirely or something should be put in place to prevent overwriting parameters named the same as a server variable.</p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/07/08/mvc-controller-action-security-hole/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/07/08/mvc-controller-action-security-hole/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/07/08/mvc-controller-action-security-hole/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/07/08/mvc-controller-action-security-hole/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Squaredroot?a=1-GzLCoZvk8:rjzD1tmhlWA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Squaredroot?a=1-GzLCoZvk8:rjzD1tmhlWA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/Squaredroot?i=1-GzLCoZvk8:rjzD1tmhlWA:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Squaredroot/~4/1-GzLCoZvk8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/07/08/mvc-controller-action-security-hole/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.squaredroot.com/2008/07/08/mvc-controller-action-security-hole/</feedburner:origLink></item>
	</channel>
</rss>
