<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>SquaredRoot</title>
 
 <link href="http://squaredroot.com/" />
 <updated>2011-07-15T13:58:00-04:00</updated>
 <id>http://squaredroot.com/</id>
 <author>
   <name>Troy Goode</name>
   <email>troygoode@gmail.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Squaredroot" /><feedburner:info uri="squaredroot" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>38.874979</geo:lat><geo:long>-77.114551</geo:long><entry>
   <title>PagedList can haz HtmlHelperz?</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/IYB_2QfHUac/" />
   <updated>2011-06-28T00:00:00-04:00</updated>
   <id>http://squaredroot.com/2011/06/28/pagedlist-can-haz-htmlhelperz</id>
   <content type="html">&lt;p&gt;Wow, has it already been almost two years since my &lt;a href="/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/"&gt;last post&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Back in March I made some modifications to the &lt;a href="http://github.com/troygoode/pagedlist"&gt;PagedList library&lt;/a&gt; I've been working on the last couple of years to (finally) add an HTML Helper that can generate the HTML paging code you frequently will use alongside the PagedList library. Over the last few days I have tweaked everything a bit more and am now quite happy with where the library sits.&lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;You can install via Nuget:&lt;/p&gt;

&lt;div class="commandWrapper"&gt;
  &lt;div class="commandPrompt"&gt;
    &lt;p class="command"&gt;&lt;a href="http://nuget.org/List/Packages/PagedList"&gt;PM&amp;gt; Install-Package PagedList&lt;/a&gt;&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class="commandWrapper"&gt;
  &lt;div class="commandPrompt"&gt;
    &lt;p class="command"&gt;&lt;a href="http://nuget.org/List/Packages/PagedList.Mvc"&gt;PM&amp;gt; Install-Package PagedList.Mvc&lt;/a&gt;&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Alternatively, &lt;a href="https://github.com/TroyGoode/PagedList"&gt;download the source&lt;/a&gt; straight from GitHub.&lt;/p&gt;

&lt;h2&gt;What does PagedList do again?&lt;/h2&gt;

&lt;p&gt;The first package contains the core PagedList library, which allows you to do this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;div class="code"&gt;&lt;script src="https://gist.github.com/1053069.js?file=pagedlist_example.cs"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;pre&gt;&lt;code class="csharp"&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pageSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;allProducts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;All&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//15 products&lt;/span&gt;

&lt;span class="c1"&gt;//products 1-10&lt;/span&gt;
&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;allProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToPagedList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;False&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firstPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasPreviousPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;True&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firstPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasNextPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//products 11-15&lt;/span&gt;
&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;secondPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;allProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToPagedList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secondPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;False&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secondPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsFirstPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;True&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secondPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsLastPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="https://gist.github.com/1053069"&gt;This Gist&lt;/a&gt; hosted on &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;&lt;/noscript&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;Okay, so what is PagedList.Mvc then?&lt;/h2&gt;

&lt;p&gt;The second package contains the new HTML Helper which lets you render pagers that look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/2011/06/28/pagedlist-can-haz-htmlhelperz/DefaultPagingControlStyles.png" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: All elements rendered by the HTML Helper have CSS classes applied to allow you to easily modify styling.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You call the HTML Helper like so:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;div class="code"&gt;&lt;script src="https://gist.github.com/1053136.js?file=pagedlist_mvc_examples.cshtml"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;pre&gt;&lt;code class="csharp"&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="n"&gt;Pager&lt;/span&gt; &lt;span class="n"&gt;Configurations&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="n"&gt;Paging&lt;/span&gt; &lt;span class="n"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Minimal&lt;/span&gt; &lt;span class="n"&gt;Paging&lt;/span&gt; &lt;span class="n"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Minimal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Minimal&lt;/span&gt; &lt;span class="n"&gt;Paging&lt;/span&gt; &lt;span class="n"&gt;Control&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;Page&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MinimalWithPageCountText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Minimal&lt;/span&gt; &lt;span class="n"&gt;Paging&lt;/span&gt; &lt;span class="n"&gt;Control&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MinimalWithItemCountText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt; &lt;span class="n"&gt;Numbers&lt;/span&gt; &lt;span class="n"&gt;Only&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageNumbersOnly&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Only&lt;/span&gt; &lt;span class="n"&gt;Show&lt;/span&gt; &lt;span class="n"&gt;Five&lt;/span&gt; &lt;span class="n"&gt;Pages&lt;/span&gt; &lt;span class="n"&gt;At&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnlyShowFivePagesAtATime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="p"&gt;----------------------------------------&lt;/span&gt; &lt;span class="p"&gt;--&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Custom&lt;/span&gt; &lt;span class="n"&gt;Pager&lt;/span&gt; &lt;span class="n"&gt;Configurations&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Custom&lt;/span&gt; &lt;span class="n"&gt;Wording&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Spanish&lt;/span&gt; &lt;span class="n"&gt;Translation&lt;/span&gt; &lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;LinkToFirstPageFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;&amp;lt; Primera&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LinkToPreviousPageFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt; Anterior&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LinkToNextPageFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Siguiente &amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LinkToLastPageFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Ultima &amp;gt;&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Show&lt;/span&gt; &lt;span class="n"&gt;Range&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;Each&lt;/span&gt; &lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;FunctionToDisplayEachPageNumber&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageSize&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;MaximumPageNumbersToDisplay&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;With&lt;/span&gt; &lt;span class="n"&gt;Delimiter&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IPagedList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnePageOfProducts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;DelimiterBetweenPageNumbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;|&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="https://gist.github.com/1053136"&gt;This Gist&lt;/a&gt; hosted on &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;&lt;/noscript&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;Customizing the Rendering Options&lt;/h2&gt;

&lt;p&gt;There are several out-of-the-box render configurations as you can see above, and you can also pass ad-hoc render configurations to the render method (also shown above). Sometimes, though, you want to create a render configuration that will be used repeatedly throughout your application. This is easy to do as well:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;div class="code"&gt;&lt;script src="https://gist.github.com/1053159.js?file=MyRenderOptions.cs"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;pre&gt;&lt;code class="csharp"&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyRenderOptions&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PagedList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mvc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListRenderOptions&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MyRenderOptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;DisplayLinkToFirstPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;DisplayLinkToLastPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;DisplayLinkToIndividualPages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;LinkToPreviousPageFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt; Go Back&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;LinkToNextPageFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Go Forward &amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//use like so:&lt;/span&gt;
&lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PagedListPager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myPagedList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MyRenderOptions&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="https://gist.github.com/1053159"&gt;This Gist&lt;/a&gt; hosted on &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;&lt;/noscript&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;For more information on the available rendering option settings, check &lt;a href="https://github.com/TroyGoode/PagedList/blob/master/src/PagedList.Mvc/PagedListRenderOptions.cs"&gt;PagedListRenderingOptions.cs&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=IYB_2QfHUac:P8wuLpDqZUY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/IYB_2QfHUac" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2011/06/28/pagedlist-can-haz-htmlhelperz/</feedburner:origLink></entry>
 
 <entry>
   <title>Spearmen, Javelin Throwers, and the State Pattern. Oh My!</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/BC_18eBRGqo/" />
   <updated>2009-08-15T00:00:00-04:00</updated>
   <id>http://squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my</id>
   <content type="html">&lt;p&gt;Last week one of Ayende/Oren's posts caught my eye: &lt;a href="http://ayende.com/Blog/archive/2009/08/05/let-the-fighting-commence.aspx"&gt;Let the fighting commence!&lt;/a&gt; In it he discussed &lt;a href="http://www.thecodespring.com/2009/08/interface-overload.html"&gt;a blog post seen on Jamie Farser's blog&lt;/a&gt;, where Jamie discusses some design difficulties he has run into while designing a turn-based game similar to Axis &amp;amp; Allies named &lt;a href="http://code.google.com/p/everland/"&gt;&lt;em&gt;Everland&lt;/em&gt;&lt;/a&gt;. Since then I've been following Jamie's progress (&lt;a href="http://www.thecodespring.com/2009/08/state-pattern.html"&gt;first try&lt;/a&gt;, &lt;a href="http://www.thecodespring.com/2009/08/state-pattern-part-15.html"&gt;further exploration&lt;/a&gt;, &lt;a href="http://www.thecodespring.com/2009/08/state-pattern-part-2-of.html"&gt;second try&lt;/a&gt;, &lt;a href="http://www.thecodespring.com/2009/08/state-pattern-part-3.html"&gt;third try&lt;/a&gt;, &lt;a href="http://www.thecodespring.com/2009/08/state-pattern-transitions.html"&gt;even further exploration&lt;/a&gt;) as he tries to take some of Ayende's advice and implement the state pattern. Like Jamie, I am fairly new to the state pattern - sure I've read about it plenty (starting in &lt;a href="http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124"&gt;Head First Design Patterns&lt;/a&gt; - a must have!), but I honestly have just never implemented it "for reals." In my back &amp;amp; forth with Jamie I realized that it was time to put up or shut up - if I'm going to offer criticism I should also offer up an alternative solution.&lt;/p&gt;

&lt;h2&gt;The Problem&lt;/h2&gt;


&lt;p&gt;Let's say we have a game where the board is made up of six-side polygons ("hexes", if you will) and each hex can contain a unit like a spearman or a javelin thrower. Each unit on the board belongs to a player who can take turns moving his units, telling his units to attack other player's units, etc. Some units have different capabilities than other units - a spearman must be within 1 hex of another unit to attack that unit, whereas a javelin thrower can be 2 units away. How do we design the application in such a way that:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;The game engine doesn't need to know specifics about each unit (such as range of attack).&lt;/li&gt;
    &lt;li&gt;A unit's capabilities may change during the course of gameplay (such as a spearman being upgraded to a javelin thrower).&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;My Solution&lt;/h2&gt;


&lt;p&gt;Before we look at the code, lets run through what is going to happen in-game.&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;The user selects one of their units, then selects an opposing unit somewhere else on the gameboard, then clicks an "Attack" button.&lt;/li&gt;
    &lt;li&gt;The game engine creates a context (deriving from &lt;strong&gt;ITurnContext&lt;/strong&gt;) that describes what the user has asked to do. In our case, an &lt;strong&gt;AttackContext &lt;/strong&gt;is created containing references to the attacking unit and the defending unit.&lt;/li&gt;
    &lt;li&gt;That context is then passed into the &lt;em&gt;ExecuteTurn &lt;/em&gt;method of the attacking &lt;strong&gt;Unit&lt;/strong&gt;, which then passes it along into the &lt;em&gt;Handle &lt;/em&gt;method of its &lt;em&gt;CurrentState &lt;/em&gt;property (which is an object deriving from &lt;strong&gt;UnitState&lt;/strong&gt;). Our attacker's &lt;em&gt;CurrentState &lt;/em&gt;property is currently &lt;strong&gt;Spearman&lt;/strong&gt;, but could just as easily be &lt;strong&gt;JavelinThrower&lt;/strong&gt;. Changing a unit from melee to ranged is as simple as changing the state of that unit.&lt;/li&gt;
    &lt;li&gt;Our &lt;strong&gt;Spearman &lt;/strong&gt;state derives from &lt;strong&gt;UnitState&lt;/strong&gt;, and the &lt;strong&gt;UnitState &lt;/strong&gt;base class' &lt;em&gt;Handle &lt;/em&gt;method uses &lt;a href="http://en.wikipedia.org/wiki/Double_dispatch"&gt;double dispatch&lt;/a&gt; to forward the &lt;em&gt;Handle &lt;/em&gt;request on to the appropriate method of our subclass. In our case that would be the &lt;em&gt;Handle&lt;/em&gt;(&lt;em&gt;AttackContext&lt;/em&gt;) method of the &lt;em&gt;Spearman &lt;/em&gt;class.&lt;/li&gt;
    &lt;li&gt;Our &lt;strong&gt;Spearman &lt;/strong&gt;class' &lt;em&gt;Handle &lt;/em&gt;method then checks to see if the unit is within range to attack the defending unit - if it is, an &lt;strong&gt;AttackCommand &lt;/strong&gt;is returned denoting who the attacker and the defender are; if it isn't, a &lt;strong&gt;MovementCommand &lt;/strong&gt;is returned denoting which hex to move to.&lt;/li&gt;
    &lt;li&gt;The &lt;strong&gt;Unit &lt;/strong&gt;class then calls &lt;em&gt;Execute &lt;/em&gt;on the returned command, causing the movement or attack operation to be, well, executed.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Let's go through each of the above steps and take a look at the code involved one by one. Skipping the first step (the UI), we'll move on to where the game engine is creating an &lt;strong&gt;AttackContext &lt;/strong&gt;and passing it into the attacking &lt;strong&gt;Unit&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="brush: csharp; toolbar: false;"&gt;Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});&lt;/pre&gt;


&lt;p&gt;Okay, easy enough. Moving on we can see the &lt;strong&gt;Unit &lt;/strong&gt;class' &lt;em&gt;ExecuteTurn &lt;/em&gt;method pass the context to its &lt;em&gt;CurrentState &lt;/em&gt;property's &lt;em&gt;Handle &lt;/em&gt;method:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class Unit
{
    public Hex Location { get; set; }
    public int Health { get; set; }
    public UnitState CurrentState { get; set; }

    public void ExecuteTurn(ITurnContext context)
    {
        CurrentState.Handle(context).Execute();
    }
}&lt;/pre&gt;


&lt;p&gt;Our attacking unit's &lt;em&gt;CurrentState &lt;/em&gt;property is currently set to an instance of &lt;strong&gt;Spearman&lt;/strong&gt;, but before we take a look at that class we'll take a look at its base class (&lt;strong&gt;UnitState &lt;/strong&gt;- which is doing double dispatch to the &lt;strong&gt;Spearman&lt;/strong&gt;'s &lt;em&gt;Handle &lt;/em&gt;method):&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public abstract class UnitState
{
    private static readonly Dictionary Dispatch = new Dictionary();

    static UnitState()
    {
        foreach (var t in Assembly.GetCallingAssembly().GetTypes().Where(t =&amp;gt; t.IsSubclassOf(typeof (UnitState))))
            foreach (var mi in t.GetMethods().Where(mi =&amp;gt; mi.Name == "Handle" &amp;amp;&amp;amp; mi.GetParameters().Length &amp;gt; 0))
                Dispatch.Add(((Int64) t.GetHashCode() &amp;lt;&amp;lt; 32) + mi.GetParameters()[0].ParameterType.GetHashCode(), mi);
    }

    public IUnitCommand Handle(ITurnContext context)
    {
        var hash = ((Int64) GetType().GetHashCode() &amp;lt;&amp;lt; 32) + context.GetType().GetHashCode();
        return Dispatch.ContainsKey(hash)
                ? Dispatch[hash].Invoke(this, new[] {context}) as IUnitCommand
                : new NullCommand();
    }
}&lt;/pre&gt;


&lt;p&gt;The Spearman class' Handle method is then invoked:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class Spearman : UnitState
{
    public IUnitCommand Handle(AttackContext context)
    {
        if (context.Attacker.Location.DistanceTo(context.Defender.Location) == 1)
            return new AttackCommand(context);
        return new MovementCommand(new MovementContext
                                    {
                                        UnitToMove = context.Attacker,
                                        HexToMoveTo =
                                            context.Attacker.Location .FindClosestSurroundingHexTo( context.Defender.Location)
                                    });
    }
}&lt;/pre&gt;


&lt;p&gt;Notice that the only concern &lt;strong&gt;Spearman &lt;/strong&gt;currently has when handling an attack context is ensuring that it gets within range and then attacks the target. We'll see an example of a&lt;strong&gt; JavelinThrower &lt;/strong&gt;later. Finally we'll peek at what the &lt;strong&gt;MovementCommand &lt;/strong&gt;and &lt;strong&gt;AttackCommand &lt;/strong&gt;actually do:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MovementCommand : IUnitCommand
{
    private readonly MovementContext _movementContext;

    public MovementCommand(MovementContext movementContext)
    {
        _movementContext = movementContext;
    }

    #region IUnitCommand Members

    public void Execute()
    {
        _movementContext.UnitToMove.Location = _movementContext.HexToMoveTo;
    }

    #endregion
}

public class AttackCommand : IUnitCommand
{
    private readonly AttackContext _attackContext;

    public AttackCommand(AttackContext attackContext)
    {
        _attackContext = attackContext;
    }

    #region IUnitCommand Members

    public void Execute()
    {
        _attackContext.Defender.Health -= 10;
    }

    #endregion
}&lt;/pre&gt;


&lt;p&gt;Before we move on, here is the promised &lt;strong&gt;JavelinThrower &lt;/strong&gt;class:&lt;/p&gt;

&lt;pre class="brush:csharp;"&gt;public IUnitCommand Handle(AttackContext context)
{
    if (context.Attacker.Location.DistanceTo(context.Defender.Location) &amp;lt;= 2)
        return new AttackCommand(context);
    return new MovementCommand(new MovementContext
                                {
                                    UnitToMove = context.Attacker,
                                    HexToMoveTo =
                                        context.Attacker.Location .FindClosestSurroundingHexTo( context.Defender.Location)
                                });
}&lt;/pre&gt;


&lt;p&gt;Obviously &lt;strong&gt;JavelinThrower &lt;/strong&gt;&amp;amp; &lt;strong&gt;Spearman &lt;/strong&gt;currently only differ in the range at which they can attack (&amp;lt;=2 and &amp;lt;= 1, respectively), so the code in their &lt;em&gt;Handle &lt;/em&gt;methods could be abstracted out using the &lt;a href="http://en.wikipedia.org/wiki/Strategy_pattern"&gt;Strategy Pattern&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Prove It!&lt;/h2&gt;


&lt;p&gt;So now that we've had a chance to see the code involved the question comes down to: does it actually work? Here are our unit tests:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;[Fact]
public void JavelinThrower_moves_to_two_hexes_away_and_attacks()
{
    //starting point
    Assert.Equal(4, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(100, Defender.Health);

    //turn one - moves closer
    Attacker.ExecuteTurn(new AttackContext { Attacker = Attacker, Defender = Defender });
    Assert.Equal(3, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(100, Defender.Health);

    //turn two - moves closer
    Attacker.ExecuteTurn(new AttackContext { Attacker = Attacker, Defender = Defender });
    Assert.Equal(2, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(100, Defender.Health);

    //turn three - attacks
    Attacker.ExecuteTurn(new AttackContext { Attacker = Attacker, Defender = Defender });
    Assert.Equal(2, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(90, Defender.Health);
}

[Fact]
public void Spearman_moves_to_one_hex_away_and_attacks()
{
    //starting point
    Assert.Equal(4, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(100, Defender.Health);

    //turn one - moves closer
    Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});
    Assert.Equal(3, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(100, Defender.Health);

    //turn two - moves closer
    Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});
    Assert.Equal(2, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(100, Defender.Health);

    //turn three - moves closer
    Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});
    Assert.Equal(1, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(100, Defender.Health);

    //turn four - attacks
    Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});
    Assert.Equal(1, Attacker.Location.DistanceTo(Defender.Location));
    Assert.Equal(90, Defender.Health);
}&lt;/pre&gt;


&lt;p&gt;And the results...&lt;/p&gt;

&lt;p&gt;&lt;img class="alignnone size-full wp-image-568" title="Spearman &amp;amp; Javelin Thrower Tests Passed!" src="/img/wordpress/Spearman-JavelinThrower-Tests-Passed.PNG" alt="Spearman &amp;amp; Javelin Thrower Tests Passed!" width="426" height="129" /&gt;&lt;/p&gt;

&lt;p&gt;Yay!&lt;/p&gt;

&lt;p&gt;So that is the road I went down, but what I really want to know is how would &lt;em&gt;you &lt;/em&gt;solve this problem? If you'd like to take a deeper look at my code, download it and give it a try yourself:&lt;/p&gt;

&lt;p&gt;&lt;a href="/files/wordpress/EverlandStatePattern.zip"&gt;EverlandStatePattern.zip&lt;/a&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=BC_18eBRGqo:HxZZRcPaAZ4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/BC_18eBRGqo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/</feedburner:origLink></entry>
 
 <entry>
   <title>MVC Membership Starter Kit Released</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/ytgcwdlSSZA/" />
   <updated>2009-08-07T00:00:00-04:00</updated>
   <id>http://squaredroot.com/2009/08/07/mvcmembership-release-1-0</id>
   <content type="html">&lt;p&gt;Almost six months after the &lt;a href="http://haacked.com/archive/2009/03/18/aspnet-mvc-rtw.aspx"&gt;official release of Asp.Net MVC 1.0&lt;/a&gt; and nearly a year after &lt;a href="http://www.squaredroot.com/2008/09/06/mvc-membership-preview-5/"&gt;the last release of the starter kit&lt;/a&gt;, I've finally rewritten and released the Asp.Net MVC Membership Starter Kit. If you're already familiar with what it is and want to grab it, you can find the release on the &lt;a href="http://mvcmembership.codeplex.com"&gt;CodePlex project site&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mvcmembership.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=22875"&gt;http://mvcmembership.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=22875&lt;/a&gt;&lt;/p&gt;

&lt;!--more--&gt;


&lt;h2&gt;What is the Asp.Net MVC Membership Starter Kit?&lt;/h2&gt;


&lt;p&gt;The starter kit currently consists of two things:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;A sample website containing the controllers, models, and views needed to administer users &amp;amp; roles.&lt;/li&gt;
    &lt;li&gt;A library that provides testable interfaces for administering users &amp;amp; roles and concrete implementations of those interfaces that wrap the built-in Asp.Net Membership &amp;amp; Roles providers.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;How do I use it?&lt;/h2&gt;


&lt;p&gt;In Asp.Net MVC 1 there isn't a great story for packaging &amp;amp; sharing controllers, views, and other resources so we'll need to follow a few manual steps:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;After getting the source code build it using your preferred IDE or using the included &lt;strong&gt;Build.Debug.bat&lt;/strong&gt; or &lt;strong&gt;Build.Release.bat&lt;/strong&gt; batch files.&lt;/li&gt;
    &lt;li&gt;Grab the &lt;strong&gt;MvcMembership.dll&lt;/strong&gt; assembly and place it wherever you're including external libraries in your project. Add a reference to the assembly to your Asp.Net MVC application.&lt;/li&gt;
    &lt;li&gt;Copy the &lt;strong&gt;UserAdministrationController.cs&lt;/strong&gt; file from the &lt;em&gt;SampleWebsite&lt;/em&gt;'s &lt;em&gt;Controllers &lt;/em&gt;directory to your app's &lt;em&gt;Controllers &lt;/em&gt;directory.&lt;/li&gt;
    &lt;li&gt;Copy the &lt;strong&gt;ISmtpClient.cs&lt;/strong&gt; file, &lt;strong&gt;SmtpClientProxy.cs&lt;/strong&gt; file, and &lt;strong&gt;UserAdministration&lt;/strong&gt; folder from the &lt;em&gt;SampleWebsite&lt;/em&gt;'s &lt;em&gt;Models &lt;/em&gt;folder to your app's &lt;em&gt;Models &lt;/em&gt;folder.&lt;/li&gt;
    &lt;li&gt;Copy the &lt;strong&gt;UserAdministration&lt;/strong&gt; folder from the &lt;em&gt;SampleWebsite&lt;/em&gt;'s &lt;em&gt;Views &lt;/em&gt;folder to your app's &lt;em&gt;Views &lt;/em&gt;folder.&lt;/li&gt;
    &lt;li&gt;Make sure you've configured your &lt;strong&gt;web.config&lt;/strong&gt; properly for Membership and Roles. If you aren't sure of how to do this, take a look at the first two articles in &lt;a href="http://www.4guysfromrolla.com/articles/120705-1.aspx"&gt;this series by Scott Mitchell at 4GuysFromRolla&lt;/a&gt;.&lt;/li&gt;
    &lt;li&gt;Finally, add the following code to your &lt;strong&gt;global.asax&lt;/strong&gt; to keep the membership system updated with each user's last activity date:&lt;/li&gt;
&lt;/ol&gt;


&lt;pre class="brush: csharp"&gt;protected void Application_AuthenticateRequest()
{
    if(User != null)
        Membership.GetUser(true);
}&lt;/pre&gt;


&lt;h2&gt;What is new since the last release?&lt;/h2&gt;


&lt;p&gt;Well, the last release was for &lt;a href="http://mvcmembership.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=16809"&gt;Preview 5&lt;/a&gt;, so at the very least the project has been updated for Beta and finally Release. Moreover, the project has been completely rewritten from scratch - a major undertaking that was the primary cause of the long delay between releases. Why the rewrite? Two reasons:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;The &lt;a href="http://mvcmembership.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=12215"&gt;first release of the Starter Kit&lt;/a&gt; was for Preview 2 of the MVC framework. A lot changed between Preview 2 and Release - A LOT. A lot of the features of the first starter kit were rolled into the OTOB experience (such as login and registration), so I shifted the scope of the project more squarely into the realm of user &amp;amp; role administration. Unfortunately all of these major changes took a toll on the source - I was no longer happy working in the source as it was written for many reasons and thus wanted a rewrite. One of those reasons was...&lt;/li&gt;
    &lt;li&gt;Previous releases had no (as in zero, less than one, nada) unit tests. This became increasingly unacceptable to me and trying to add unit tests after-the-fact was a nightmare. Instead I rewrote the project using TDD.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Alright, so that was basically the long-winded spiel to prepare you for the bad news: the project regressed from a functionality perspective. During the course of the rewrite things some things didn't make it in - chief among them is the OpenID integration. I encourage everyone to take a look at the Maarten Balliauw (an MvcMembership contributor) blog post on &lt;a href="http://blog.maartenballiauw.be/post/2009/07/27/Authenticating-users-with-RPXNow-%28in-ASPNET-MVC%29.aspx"&gt;authenticating via RPX in MVC&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;What comes next?&lt;/h2&gt;


&lt;p&gt;The primary motivator for me getting off my but after nearly a year and finishing up this release is my desire to convert it to an &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx"&gt;"area" for use in MVC 2&lt;/a&gt;. Packaging reusable components like this has been a sore spot for the current MVC framework and I'm glad to see the blue badges are going to provide a common solution. Along with that I'll likely try to add RPX authentication ala Maarten's post.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=ytgcwdlSSZA:FqH0ZXccWS4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/ytgcwdlSSZA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2009/08/07/mvcmembership-release-1-0/</feedburner:origLink></entry>
 
 <entry>
   <title>Return of the PagedList</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/5aXVMoBuJnM/" />
   <updated>2009-06-15T00:00:00-04:00</updated>
   <id>http://squaredroot.com/2009/06/15/return-of-the-pagedlist</id>
   <content type="html">&lt;p&gt;It has been nearly a year since I &lt;a href="http://www.squaredroot.com/2008/07/08/PagedList-Strikes-Back/"&gt;posted&lt;/a&gt; an updated version of the PagedList&amp;lt;T&amp;gt; functionality originally &lt;a href="http://blog.wekeroad.com/blog/aspnet-mvc-pagedlistt"&gt;created by Scott Guthrie and posted by Rob Conery&lt;/a&gt;. Since then I have used the class in a number of projects and find it indispensable.&lt;/p&gt;

&lt;p&gt;A few days ago, Craig Stuntz reported an interesting observation: when the first page is returned, the class performs a Skip(0). Suprisingly, &lt;a href="http://blogs.teamb.com/craigstuntz/2009/06/10/38313/"&gt;this is not free&lt;/a&gt;. 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...&lt;/p&gt;

&lt;!--more--&gt;


&lt;ul&gt;
    &lt;li&gt;The source is now available on CodePlex: &lt;a href="http://pagedlist.codeplex.com"&gt;http://pagedlist.codeplex.com&lt;/a&gt;. This should make finding and downloading the code easier than finding the correct blog entry on some dude's blog.&lt;/li&gt;
    &lt;li&gt;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's taxonomy.&lt;/li&gt;
    &lt;li&gt;Further incremental changes can be found in the Change Log on the CodePlex project site.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;&lt;a href="http://pagedlist.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28585#ReleaseFiles"&gt;Download from CodePlex&lt;/a&gt;&lt;/h3&gt;


&lt;br /&gt;


&lt;h4&gt;IPagedList&amp;lt;T&amp;gt;.cs&lt;/h4&gt;


&lt;pre class="brush: csharp"&gt;using System.Collections.Generic;

namespace PagedList
{
    public interface IPagedList&amp;lt;T&amp;gt; : IList&amp;lt;T&amp;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; }
    }
}&lt;/pre&gt;


&lt;h4&gt;PagedList&amp;lt;T&amp;gt;.cs&lt;/h4&gt;


&lt;pre class="brush: csharp"&gt;using System;
using System.Collections.Generic;
using System.Linq;

namespace PagedList
{
    public class PagedList&amp;lt;T&amp;gt; : List&amp;lt;T&amp;gt;, IPagedList&amp;lt;T&amp;gt;
    {
        public PagedList(IEnumerable&amp;lt;T&amp;gt; superset, int index, int pageSize)
        {
            // set source to blank list if superset is null to prevent exceptions
            var source = superset == null
                                    ? new List&amp;lt;T&amp;gt;().AsQueryable()
                                    : superset.AsQueryable();

            TotalItemCount = source.Count();
            PageSize = pageSize;
            PageIndex = index;
            if (TotalItemCount &amp;gt; 0)
                PageCount = (int) Math.Ceiling(TotalItemCount/(double) PageSize);
            else
                PageCount = 0;

            if (index &amp;lt; 0)
                throw new ArgumentOutOfRangeException("index", index, "PageIndex cannot be below 0.");
            if (pageSize &amp;lt; 1)
                throw new ArgumentOutOfRangeException("pageSize", pageSize, "PageSize cannot be less than 1.");

            // add items to internal list
            if (TotalItemCount &amp;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 &amp;gt; 0; }
        }

        public bool HasNextPage
        {
            get { return PageIndex &amp;lt; (PageCount - 1); }
        }

        public bool IsFirstPage
        {
            get { return PageIndex &amp;lt;= 0; }
        }

        public bool IsLastPage
        {
            get { return PageIndex &amp;gt;= (PageCount - 1); }
        }
    }
}&lt;/pre&gt;


&lt;h4&gt;PagedListExtensions.cs&lt;/h4&gt;


&lt;pre class="brush: csharp"&gt;using System.Collections.Generic;
using System.Linq;

namespace PagedList
{
    public static class PagedListExtensions
    {
        public static IPagedList&amp;lt;T&amp;gt; ToPagedList&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; superset, int index, int pageSize)
        {
            return new PagedList&amp;lt;T&amp;gt;(superset, index, pageSize);
        }
    }
}&lt;/pre&gt;


&lt;h4&gt;PagedListFacts.cs&lt;/h4&gt;


&lt;pre class="brush: csharp; collapse: true"&gt;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 = () =&amp;gt; new PagedList&amp;lt;object&amp;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 = () =&amp;gt; data.ToPagedList(-1, 1);

            //assert
            Assert.Throws&amp;lt;ArgumentOutOfRangeException&amp;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 = () =&amp;gt; data.ToPagedList(0, 0);

            //assert
            Assert.Throws&amp;lt;ArgumentOutOfRangeException&amp;gt;(act);
        }

        [Fact]
        public void Null_Data_Set_Doesnt_Return_Null()
        {
            //act
            var pagedList = new PagedList&amp;lt;object&amp;gt;(null, 0, 10);

            //assert
            Assert.NotNull(pagedList);
        }

        [Fact]
        public void Null_Data_Set_Returns_Zero_Pages()
        {
            //act
            var pagedList = new PagedList&amp;lt;object&amp;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&amp;lt;object&amp;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);
        }
    }
}&lt;/pre&gt;


&lt;p&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=5aXVMoBuJnM:VNyXGFmfU1A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/5aXVMoBuJnM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2009/06/15/return-of-the-pagedlist/</feedburner:origLink></entry>
 
 <entry>
   <title>Creating an MVC Project in Visual Studio 2010</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/skvOQjhWJJ8/" />
   <updated>2009-06-09T00:00:00-04:00</updated>
   <id>http://squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010</id>
   <content type="html">&lt;p&gt;Earlier today &lt;a href="http://www.haacked.com/archive/2009/06/09/aspnetmvc-vs10beta1-roadmap.aspx"&gt;Phil Haack announced&lt;/a&gt; that the Asp.Net MVC installer for Visual Studio 2010 Beta 1 is &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527"&gt;now available on CodePlex&lt;/a&gt; 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'm happy to say that the basic experience went flawlessly for me, though it appears &lt;a href="http://weblogs.asp.net/jacqueseloff/archive/2009/06/09/troubleshooting-the-mvc-installer-for-visual-studio-2010-beta-1.aspx"&gt;that may not hold true for everyone&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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 &lt;a href="http://www.microsoft.com/downloadS/details.aspx?familyid=3296BB4F-D8BA-4CFD-AA95-A424C5913F6B&amp;amp;displaylang=en"&gt;full install 2 ISO download (1.1 GB)&lt;/a&gt; or a &lt;a href="http://www.microsoft.com/downloadS/details.aspx?familyid=75CBCBCD-B0E8-40EA-ADAE-85714E8984E3&amp;amp;displaylang=en"&gt;lightweight (5 MB) "web install" package&lt;/a&gt;. 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'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.&lt;/p&gt;

&lt;p&gt;Once Visual Studio has finished installing, download and install the &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527"&gt;Asp.Net MVC 1.1 Installer for Visual Studio 2010 from CodePlex&lt;/a&gt;. While you'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:&lt;/p&gt;

&lt;blockquote&gt;Unzip "ASP.NET MVC Snippets.zip" into "C:\Users\&amp;lt;username&amp;gt;\Documents\Visual Studio 10\Code Snippets\Visual Web Developer\My HTML Snippets", where "C:\" is your OS drive.&lt;/blockquote&gt;


&lt;p&gt;If you encounter any difficulties with the installer, check out this &lt;a href="http://weblogs.asp.net/jacqueseloff/archive/2009/06/09/troubleshooting-the-mvc-installer-for-visual-studio-2010-beta-1.aspx"&gt;blog post by Jacques Eloff&lt;/a&gt;. 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:&lt;/p&gt;

&lt;p&gt;&lt;img class="size-large wp-image-433" title="Visual Studio 2010 Beta 1 (First Boot)" src="/img/wordpress/1-vs2010-first-boot-1024x736.jpg" alt="The new startup screen of VS2010." width="480" height="345" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img class="size-thumbnail wp-image-437" title="Create a New MVC Application" src="/img/wordpress/2-creating-mvc-project-150x150.jpg" alt="The new New Project dialog." width="150" height="150" /&gt;&lt;/p&gt;

&lt;p&gt;From here, you can launch the new New Project dialog either via the File menu or by clicking "Projects" on the left side of the startup screen and then clicking the "New Project" icon. If the Asp.Net MVC 1.1 installer has been correctly installed, you will find a "ASP.NET MVC Web Application" entry under the "Web" category in the New Project dialog. Fiddle with the Name, Location, and Solution Name as always and then click OK to create your application.&lt;/p&gt;

&lt;p&gt;&lt;img class="size-thumbnail wp-image-438" title="Create Test Project Dialog" src="/img/wordpress/3-create-test-project-150x150.jpg" alt="Just click no and setup your own test project using not-MSTest." width="150" height="150" /&gt;&lt;/p&gt;

&lt;p&gt;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't a big deal, as I prefer to setup my test projects manually and don't see a lot of value in the dialog, but I'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...&lt;/p&gt;

&lt;p&gt;&lt;img class="size-large wp-image-436" title="Created MVC Application But Cant See Anything" src="/img/wordpress/4-project-created-1024x736.jpg" alt="Not entirely legible." width="480" height="344" /&gt;&lt;/p&gt;

&lt;p&gt;The culprit here is that in Visual Studio 2008 I use a dark theme based off the Vibrant Ink-ish theme &lt;a href="http://blog.wekeroad.com/blog/textmate-theme-for-visual-studio-take-2/"&gt;Rob Conery posted a long time ago&lt;/a&gt;. 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;amp; a jump through "Tools" &amp;gt; "Import and Export Settings..." allowed me to import the defaults, thus making my color scheme readable, if a bit too vanilla.&lt;/p&gt;

&lt;p&gt;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's Controllers folder and select "Add &amp;gt; Controller...". 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 "Add View...". I was pleased to find that neither of these features had been lost and were working as expected.&lt;/p&gt;

&lt;p&gt;&lt;img class="size-medium wp-image-452" title="Snippets Dialog" src="/img/wordpress/9-choosing-actionlink-snippet-300x206.jpg" alt="Note to self: delete VB snippets." width="300" height="206" /&gt;&lt;/p&gt;

&lt;p&gt;So now I've created a ProductController with various actions as well as a basic view for the controller's Index action, but I don'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 &amp;lt;li&amp;gt;&amp;lt;/li&amp;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. &lt;em&gt;(On a side note, this makes it much more likely that I'll use them - the quickest way to get me to not use a Visual Studio feature is to make me deal with the horribly slow loading toolbar).&lt;/em&gt; The context-menu inside of views has an "Insert Snippet..." 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 "My HTML Snippets" folder. Selecting that folder presents you with a list of many basic HTML helper snippets.&lt;/p&gt;

&lt;p&gt;In this case I wanted to use the first one, actionlink, to create a new call to Html.ActionLink(...). Selecting it then inserted the Html helper text as I would expect, and highlighted the arguments for the link's text and action also as I would expect. I did notice that the snippet doesn'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.&lt;/p&gt;

&lt;p&gt;With that done I hit F5 and was able to browse to my Product controller'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's integration should be quite good.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=skvOQjhWJJ8:ohiwzi-0csc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/skvOQjhWJJ8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2009/06/09/creating-an-mvc-project-in-visual-studio-2010/</feedburner:origLink></entry>
 
 <entry>
   <title>DevPocalypse ? A *Basic* Asp.Net MVC + jQuery Game</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/6qnXyODkVI4/" />
   <updated>2008-12-12T00:00:00-05:00</updated>
   <id>http://squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample</id>
   <content type="html">&lt;p&gt;Last weekend I had the privilege of speaking at the second &lt;a href="http://www.novacodecamp.org/"&gt;Northern Virginia CodeCamp&lt;/a&gt; of the year, thanks to an invitation from &lt;a href="http://thequeue.net/blog/"&gt;Jeff Schoolcraft&lt;/a&gt;. For those of you who were able to make it to the event, thanks for attending, and make sure to &lt;a href="http://codecampevals.com/"&gt;fill out an eval&lt;/a&gt;! 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.&lt;/p&gt;

&lt;!--more--&gt;


&lt;h2&gt;DevPocalypse&lt;/h2&gt;


&lt;p&gt;&lt;strong&gt;ASP.Net MVC + jQuery = Simple Multiplayer Action&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Letâ€™s take a gander at what the app looks like when it is running:&lt;/p&gt;

&lt;p&gt;&lt;a rel="lightview" href="/img/wordpress/DevPocalypse-Screenshot_2.jpg"&gt;&lt;img style="border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto" title="DevPocalypse-Screenshot" src="/img/wordpress/DevPocalypse-Screenshot_thumb.jpg" border="0" alt="DevPocalypse-Screenshot" width="426" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;em&gt;your&lt;/em&gt; 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 &lt;em&gt;their&lt;/em&gt; 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):&lt;/p&gt;

&lt;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;"&gt;
&lt;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;"&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; $(document).ready(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;     updateScreen();&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     setInterval(updateScreen, updateFrequency * 1000);&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; });&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;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:&lt;/p&gt;

&lt;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;"&gt;
&lt;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;"&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web.Mvc;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; DevPocalypse.Domain;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; DevPocalypse.Domain.Repositories;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; DevPocalypse.Website.App.ModelBinders;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; DevPocalypse.Website.Controllers&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt; {&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     [Authorize]&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; GameController : Controller&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;     {&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ICharacterRepository CharacterRepository { get; set; }&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IScreenRepository ScreenRepository { get; set; }&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ViewResult Index()&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;         {&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;             ViewData[&lt;span style="color: #006080"&gt;"Title"&lt;/span&gt;] = &lt;span style="color: #006080"&gt;"Play!"&lt;/span&gt;;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View();&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;         }&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; JsonResult GetCurrentScreen(&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt;             [ModelBinder( &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;( CurrentCharacterBinder ) )]&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;             Character currentCharacter&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt;             )&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt;         {&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt;             &lt;span style="color: #008000"&gt;// IE will cache aggressively if we don't set our expiration date&lt;/span&gt;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt;             Response.ExpiresAbsolute = DateTime.Now.AddYears( -1 );&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;             &lt;span style="color: #008000"&gt;// get screen character is on, and a list of all characters on that screen&lt;/span&gt;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt;             var screen = ScreenRepository.Retrieve().Where( s =&amp;gt; s.ID == currentCharacter.ScreenID ).Single();&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  32:&lt;/span&gt;             var characters = CharacterRepository.Retrieve().Where( c =&amp;gt; c.ScreenID == screen.ID ).ToList();&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  33:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Json( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; { Screen = screen, MyCharacter = currentCharacter, Characters = characters } );&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  34:&lt;/span&gt;         }&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  35:&lt;/span&gt;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  36:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; MoveTo(&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  37:&lt;/span&gt;             [ModelBinder( &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;( CurrentCharacterBinder ) )]&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  38:&lt;/span&gt;             Character currentCharacter,&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  39:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; x,&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  40:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; y&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  41:&lt;/span&gt;             )&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  42:&lt;/span&gt;         {&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  43:&lt;/span&gt;             currentCharacter.X = x;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  44:&lt;/span&gt;             currentCharacter.Y = y;&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  45:&lt;/span&gt;             CharacterRepository.Update( currentCharacter );&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  46:&lt;/span&gt;         }&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  47:&lt;/span&gt;     }&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;  48:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;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 &lt;em&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;c&lt;/strong&gt;&lt;/em&gt; variables):&lt;/p&gt;

&lt;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;"&gt;
&lt;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;"&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; $(&lt;span style="color: #006080"&gt;"#"&lt;/span&gt; + id).animate({&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;     left: currentCharacters[c].X * 33,&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     top: currentCharacters[c].Y * 33&lt;/pre&gt;
&lt;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;"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; }, updateFrequency * 1000 / 4);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Gotta love jQuery. :-) 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.&lt;/p&gt;

&lt;p&gt;Thanks, and I hope to see you at the next CodeCamp!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download:&lt;/strong&gt; &lt;a href="/files/wordpress/DevPocalypse.zip"&gt;DevPocalypse.zip (762.63 kb)&lt;/a&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=6qnXyODkVI4:wXnKH0tIUpo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/6qnXyODkVI4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2008/12/12/devpocalypse-basic-multiplayer-mvc-jquery-ajax-sample/</feedburner:origLink></entry>
 
 <entry>
   <title>MVC/jQuery Presentation at NoVa CodeCamp - Dec. 6</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/gaEZjB8MY74/" />
   <updated>2008-11-24T00:00:00-05:00</updated>
   <id>http://squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008</id>
   <content type="html">&lt;p&gt;&lt;a href="http://novacodecamp.org/"&gt;&lt;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" /&gt;&lt;/a&gt;&lt;a href="http://thequeue.net/blog/"&gt;Jeff Schoolcraft&lt;/a&gt; was kind enough to ask me to speak at this yearâ€™s second &lt;a href="http://novacodecamp.org/"&gt;NoVa CodeCamp&lt;/a&gt;. It is being held in two weeks on Saturday, December 6th at the Microsoft Technology Center in Reston, VA [&lt;a href="http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=12012+Sunset+Hills+Rd.++Reston,+VA+20190&amp;amp;sll=37.0625,-95.677068&amp;amp;sspn=51.089971,79.101563&amp;amp;ie=UTF8&amp;amp;z=16&amp;amp;g=12012+Sunset+Hills+Rd.++Reston,+VA+20190&amp;amp;iwloc=addr"&gt;map&lt;/a&gt;]. If youâ€™re interested in attending, please make sure you &lt;a href="https://www.clicktoattend.com/invitation.aspx?code=131469"&gt;register&lt;/a&gt; soon!&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;I donâ€™t yet have word on the final presentation schedule, but here is the abstract for the presentation I will be giving:&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Creating an AJAX MMORPG With jQuery &amp;amp; Asp.Net MVC&lt;/strong&gt;

C'mon, it's Saturday, let'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 - even in the apps we build at our day jobs. We'll see how jQuery allows us to build such a UI using AJAX and animations in a quick, cross-platform manner. We'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'll even have a fun little game to play!&lt;/blockquote&gt;


&lt;p&gt;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!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=gaEZjB8MY74:K94AMM1oLsg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/gaEZjB8MY74" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2008/11/24/mvc-jquery-presentation-at-nova-codecamp-december-6-2008/</feedburner:origLink></entry>
 
 <entry>
   <title>My PDC 2008 Agenda</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/Wbn9F5n3KdY/" />
   <updated>2008-10-23T00:00:00-04:00</updated>
   <id>http://squaredroot.com/2008/10/23/pdc-2008-agenda</id>
   <content type="html">&lt;p&gt;This Saturday Iâ€™ll be headed off to &lt;a href="http://www.weather.com/weather/tenday/USCA0638?from=36hr_topnav_undeclared"&gt;sunny&lt;/a&gt; Los Angeles for Microsoftâ€™s &lt;a href="http://microsoftpdc.com"&gt;Professional Developer Conference 2008&lt;/a&gt;. This is the first time Iâ€™ve gone and Iâ€™m really looking forward to it. Iâ€™m staying at &lt;a href="http://www.figueroahotel.com"&gt;Hotel Figueroa&lt;/a&gt;, only a couple blocks from the &lt;a href="http://www.lacclink.com"&gt;Los Angeles Convention Center&lt;/a&gt;, 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, &lt;a href="mailto:troygoode@gmail.com"&gt;drop me an email&lt;/a&gt;.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Pre-Conference / Sunday, Oct. 26&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;10:00 AM â€“ 5:45 PM&lt;/strong&gt;
&lt;a href="http://microsoftpdc.com/Agenda/Preconference.aspx#creating-rich-internet-applications-with-silverlight"&gt;Creating Rich Internet Applications with Silverlight&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Day One / Monday, Oct. 27&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;8:30 AM â€“ 11:00 AM
&lt;/strong&gt;&lt;em&gt;Keynote Address&lt;/em&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;11:00 AM â€“ 12:45 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/ES16/"&gt;A Lap Around Cloud Services (Part 1)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;12:45 PM â€“ 1:45 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/PC47/"&gt;Microsoft Expression Blend: Tips &amp;amp; Tricks&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;1:45 PM â€“ 3:30 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/PC20/"&gt;ASP.Net 4.0 Roadmap&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;3:30 PM â€“ 5:15 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/BB01/"&gt;A Lap Around Cloud Services (Part 2)&lt;/a&gt; &lt;em&gt;orâ€¦
&lt;/em&gt;&lt;a href="http://channel9.msdn.com/pdc2008/PC21/"&gt;ASP.NET MVC: A New Framework for Building Web Applications&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;5:15 PM â€“ 6:30 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/ES01/"&gt;Developing and Deploying Your First Cloud Service&lt;/a&gt; &lt;em&gt;orâ€¦&lt;/em&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/TL49/"&gt;Microsoft .NET Framework: Overview and Applications for Babies&lt;/a&gt; &lt;em&gt;orâ€¦
&lt;/em&gt;&lt;a href="http://channel9.msdn.com/pdc2008/TL17/"&gt;Windows Workflow Foundation 4.0: A First Look&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Day Two / Tuesday, Oct. 28&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;8:30 AM â€“ 12:45 PM
&lt;/strong&gt;&lt;em&gt;Keynote Address&lt;/em&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;12:45 PM â€“ 1:45 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/PC24/"&gt;Windows 7: Welcome to the Windows 7 Desktop&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;1:45 PM â€“ 3:30 PM
&lt;/strong&gt;&lt;a href="http://channel9.msdn.com/pdc2008/ES04/"&gt;Essential Cloud Storage Services&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;3:30 PM â€“ 5:15 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/PC33/"&gt;Microsoft Visual Studio: Easing ASP.NET Web Deployment&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;5:15 PM â€“ 6:30 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/TL20/"&gt;Entity Framework Futures&lt;/a&gt; &lt;em&gt;orâ€¦
&lt;/em&gt;&lt;a href="http://channel9.msdn.com/pdc2008/PC31/"&gt;ASP.NET and JQuery&lt;/a&gt; &lt;em&gt;orâ€¦
&lt;/em&gt;&lt;a href="http://channel9.msdn.com/pdc2008/ES02/"&gt;Architecting Services for the Cloud&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Day Three / Wednesday, Oct. 29&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;8:30 AM â€“ 10:30 AM
&lt;/strong&gt;&lt;em&gt;Keynote Address&lt;/em&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;10:30 AM â€“ 12:00 PM
&lt;/strong&gt;&lt;a href="http://channel9.msdn.com/pdc2008/TL06/"&gt;WCF 4.0: Building WCF Services with WF in Microsoft .NET 4.0&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;12:00 PM â€“ 1:15 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/TL43/"&gt;Microsoft XNA Game Studio: An Overview&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;1:15 PM â€“ 3:00 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/TL18/"&gt;"Oslo": Customizing and Extending the Visual Design Experience&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;3:00 PM â€“ 4:45 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/ES03/"&gt;A Day in the Life of a Cloud Service Developer&lt;/a&gt; &lt;em&gt;orâ€¦
&lt;/em&gt;&lt;a href="http://channel9.msdn.com/pdc2008/PC55/"&gt;Oomph: A Microformat Toolkit&lt;/a&gt; &lt;em&gt;orâ€¦
&lt;/em&gt;&lt;a href="http://channel9.msdn.com/pdc2008/TL28/"&gt;"Oslo": Repository and Models&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;4:45 PM â€“ 6:00 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/TL23-R/"&gt;A Lap around "Oslo"&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Day Four / Thursday, Oct. 30&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;8:30 AM â€“ 10:15 AM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/TL04/"&gt;WCF: Developing RESTful Services&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;10:15 AM â€“ 12:00 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/SYMP05/"&gt;Services Symposium: Enterprise Grade Cloud Applications&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;12:00 PM â€“ 1:45 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/ES17/"&gt;Cloud Computing: Programming in the Cloud&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;1:45 PM â€“ 3:00 PM&lt;/strong&gt;
&lt;a href="http://channel9.msdn.com/pdc2008/PC32/"&gt;ASP.NET AJAX Futures&lt;/a&gt; &lt;em&gt;orâ€¦
&lt;/em&gt;&lt;a href="http://channel9.msdn.com/pdc2008/BB27/"&gt;Workflow Services: Orchestrating Services and Business Processes Using Cloud-Based Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=Wbn9F5n3KdY:vO1IW_Yx3ds:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/Wbn9F5n3KdY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2008/10/23/pdc-2008-agenda/</feedburner:origLink></entry>
 
 <entry>
   <title>ASP.Net MVC Goes Beta!</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/3tvvja6-BDk/" />
   <updated>2008-10-16T00:00:00-04:00</updated>
   <id>http://squaredroot.com/2008/10/16/aspnet-mvc-beta-release</id>
   <content type="html">&lt;p&gt;I discovered via &lt;a href="http://www.dotnetkicks.com/aspnet/ASP_net_MVC_goes_Beta"&gt;DotNetKicks&lt;/a&gt; this afternoon that the ASP.Net MVC frameworkâ€™s beta release is now &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=a24d1e00-cd35-4f66-baa0-2362bdde0766&amp;amp;displaylang=en&amp;amp;tm"&gt;available for download from Microsoft.com&lt;/a&gt;. No release or source code is yet available from the &lt;a href="http://www.codeplex.com/aspnet"&gt;CodePlex project&lt;/a&gt;, but I expect weâ€™ll see it there soon enough. Congratulations to the team at Microsoft, RTM is knocking at the door!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=a24d1e00-cd35-4f66-baa0-2362bdde0766&amp;amp;displaylang=en&amp;amp;tm"&gt;&lt;strong&gt;Download ASP.Net MVC Beta&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;!--more--&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Changes Made Between CodePlex Preview 5 and Beta&lt;/strong&gt;

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.

&lt;strong&gt;Changes&lt;/strong&gt;
&lt;ul&gt;
    &lt;li&gt;Changed the default validation messages to be more end-user friendly.&lt;/li&gt;
    &lt;li&gt;Renamed &lt;em&gt;CompositeViewEngine&lt;/em&gt; to &lt;em&gt;AutoViewEngine&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;Added a &lt;em&gt;Url&lt;/em&gt; property to &lt;em&gt;Controller&lt;/em&gt; of type &lt;em&gt;UrlHelper&lt;/em&gt;. This makes it convenient to generate routing-based URLs from within a controller.&lt;/li&gt;
    &lt;li&gt;Added the &lt;em&gt;ActionNameSelectorAttribute&lt;/em&gt; abstract base class, which serves as the base type for &lt;em&gt;ActionNameAttribute&lt;/em&gt;. By inheriting from this base attribute class, you can create custom attributes that participate in action selection by name.&lt;/li&gt;
    &lt;li&gt;Added a new &lt;em&gt;ReleaseView&lt;/em&gt; method to &lt;em&gt;IViewEngine&lt;/em&gt; that allows custom view engines to be notified when a view is done rendering. This is useful for cleanup or for view-pooling scenarios.&lt;/li&gt;
    &lt;li&gt;Renamed the &lt;em&gt;ControllerBuilder&lt;/em&gt; method &lt;em&gt;DisposeController&lt;/em&gt; to &lt;em&gt;ReleaseController&lt;/em&gt; to fit with the pattern that is established for view engines.&lt;/li&gt;
    &lt;li&gt;Removed most of the methods on the &lt;em&gt;HtmlHelper&lt;/em&gt; class, converting them to extension methods of the &lt;em&gt;HtmlHelper&lt;/em&gt; class instead. These methods exist in a new namespace (&lt;em&gt;System.Web.Mvc.Html&lt;/em&gt;). If you are migrating from Preview 5, you must add the following element to the namespaces section of the Web.config file:&lt;em&gt;&amp;lt;add namespace="System.Web.Mvc.Html"/&amp;gt;&lt;/em&gt;

This makes it possible for you to completely replace our helper methods with your own.&lt;/li&gt;
    &lt;li&gt;Changed the default model binder (&lt;em&gt;DefaultModelBinder&lt;/em&gt;) to handle complex types. The &lt;em&gt;IModelBinder&lt;/em&gt; interface has also been changed to accept a single parameter of type &lt;em&gt;ModelBindingContext&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;Added a new &lt;em&gt;HttpVerbs&lt;/em&gt; enumeration that contains the most commonly used HTTP verbs (GET, POST, PUT, DELETE, HEAD). Also added a constructor overload to &lt;em&gt;AcceptVerbsAttribute&lt;/em&gt; 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.&lt;em&gt;[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Put)]
public ActionResult Update() {
}&lt;/em&gt;

Because it is possible to respond to HTTP verbs that are not included in the enumeration, the &lt;em&gt;AcceptVerbsAttribute&lt;/em&gt; retains the constructor that accepts an array of strings as a parameter.&lt;/li&gt;
    &lt;li&gt;Modified the &lt;em&gt;RadioButton&lt;/em&gt; 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.&lt;/li&gt;
    &lt;li&gt;Made modifications and fixes to the default project template. This includes moving script files to a new Scripts folder. The default template uses the &lt;em&gt;ModelState&lt;/em&gt; class to report validation errors.&lt;/li&gt;
    &lt;li&gt;Changed action-method selection. If two action methods match a request, but only one of those has an attribute that derives from &lt;em&gt;ActionMethodSelectorAttribute&lt;/em&gt; 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:

&lt;em&gt;public ActionResult Edit() {
//...
} [AcceptVerbs(HttpVerbs.Post)] &lt;/em&gt;

&lt;em&gt; &lt;/em&gt;&lt;em&gt; public ActionResult Edit(FormCollection form) {
//...
}&lt;/em&gt;

In Preview 5, a POST request for the &lt;em&gt;Edit&lt;/em&gt; 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 &lt;em&gt;AcceptVerb&lt;/em&gt; attribute. In this example, the first method will handle any non-POST requests for the &lt;em&gt;Edit&lt;/em&gt; action.&lt;/li&gt;
    &lt;li&gt;Added an overload for the &lt;em&gt;ViewDataDictionary.Eval&lt;/em&gt; method that accepts a format string.&lt;/li&gt;
    &lt;li&gt;Removed the &lt;em&gt;ViewName&lt;/em&gt; property from the &lt;em&gt;ViewContext&lt;/em&gt; class.&lt;/li&gt;
    &lt;li&gt;Added an &lt;em&gt;IValueProvider&lt;/em&gt; interface for value providers, along with a default implementation, &lt;em&gt;DefaultValueProvider&lt;/em&gt;. Value providers supply values that are used by the model binders when binding to a model object. The &lt;em&gt;UpdateModel&lt;/em&gt; method of the &lt;em&gt;Controller&lt;/em&gt; class has been updated to allow you to specify a custom value provider.&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;Bug Fixes&lt;/strong&gt;
&lt;ul&gt;
    &lt;li&gt;Fixed a bug in which the ignore-routes setting (created by using the &lt;em&gt;IgnoreRoute&lt;/em&gt; extension method) affected URL generation.&lt;/li&gt;
    &lt;li&gt;Fixed a view engine caching bug when the application is not in debug mode (that is, when &lt;em&gt;debug="false"&lt;/em&gt; 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.&lt;/li&gt;
    &lt;li&gt;Fixed a bug in &lt;em&gt;OutputCacheAttribute&lt;/em&gt; 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.&lt;/li&gt;
    &lt;li&gt;Fixed a bug in which &lt;em&gt;RenderPartial&lt;/em&gt; does not work when tracing is turned on.&lt;/li&gt;
    &lt;li&gt;Fixed a bug in the &lt;em&gt;Html.TextArea&lt;/em&gt; helper method in which an overload was not looking in &lt;em&gt;ViewData&lt;/em&gt; for its value when the provided value is null.&lt;/li&gt;
    &lt;li&gt;Fixed the &lt;em&gt;OutputCacheAttribute.CacheProfile&lt;/em&gt; property so that it works in Medium Trust.&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;Upgrading from CodePlex Preview 5 to Beta&lt;/strong&gt;

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.
&lt;ul&gt;
    &lt;li&gt;Update the references to the following assemblies to point to the new Beta versions of the assemblies:&lt;em&gt;System.Web.Abstractions.dll
System.Web.Routing.dll
System.Web.Mvc.dll&lt;/em&gt;

By default, these assemblies are located in the following folder:

&lt;em&gt;%ProgramFiles%Microsoft ASP.NETASP.NET MVC Beta&lt;/em&gt;&lt;/li&gt;
    &lt;li&gt;In the Web.config namespaces section, add the following namespace entry if it is not there already:&lt;em&gt;&amp;lt;add namespace="System.Web.Mvc.Html"/&amp;gt;&lt;/em&gt;&lt;/li&gt;
    &lt;li&gt;The Form HTML helper was renamed to &lt;em&gt;BeginForm&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;


&lt;p&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=3tvvja6-BDk:0pwH8VDGQhw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/3tvvja6-BDk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2008/10/16/aspnet-mvc-beta-release/</feedburner:origLink></entry>
 
 <entry>
   <title>Introduction to ASP.Net MVC for Alt.Net DC - Presentation Materials</title>
   <link href="http://feedproxy.google.com/~r/Squaredroot/~3/bxBZ5adAbTc/" />
   <updated>2008-09-24T00:00:00-04:00</updated>
   <id>http://squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials</id>
   <content type="html">&lt;p&gt;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 &lt;a href="/page/About-Me.aspx#ContactInformation"&gt;contact me&lt;/a&gt; if you have any questions. Also I owe a big thanks to &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/default.aspx"&gt;Matthew Podwysocki&lt;/a&gt; for inviting me to speak. Thanks Matt, I really enjoyed the opportunity.&lt;/p&gt;

&lt;p&gt;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:&lt;!--more--&gt;&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;&lt;strong&gt;MvcTutorials.Blog.Domain
&lt;/strong&gt;This project has the Comment &amp;amp; Post entities, as well as the repositories used to populate them.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;MvcTutorials.Blog.Domain.Bootstrap
&lt;/strong&gt;This project adds random data to the blog database for testing.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;MvcTutorials.Blog.ReferenceWebsite
&lt;/strong&gt;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.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Be sure to let me know if there are any questions or comments about tonightâ€™s presentation or this postâ€™s code!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Presentation Materials:&lt;/strong&gt;
&lt;a href="/files/wordpress/2008%2f9%2fMvcTutorial-Blog.zip"&gt;MvcTutorial-Blog.zip (307.06 kb)&lt;/a&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Squaredroot?a=bxBZ5adAbTc:pH0wNoEc8ME:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Squaredroot?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Squaredroot/~4/bxBZ5adAbTc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://squaredroot.com/2008/09/24/altdotnet-presentation-20080924-materials/</feedburner:origLink></entry>
 
 
</feed>

