[Valid Atom 1.0] This is a valid Atom 1.0 feed.


This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.


  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href=""?><feed xmlns="" xmlns:geo="" xmlns:feedburner="">
  4. <title>Troy Goode</title>
  5. <link href="" />
  6. <updated>2016-08-15T00:53:49+00:00</updated>
  7. <id></id>
  8. <author>
  9.   <name>Troy Goode</name>
  10.   <email>[email protected]</email>
  11. </author>
  13. <atom10:link xmlns:atom10="" rel="self" type="application/atom+xml" href="" /><feedburner:info uri="squaredroot" /><atom10:link xmlns:atom10="" rel="hub" href="" /><geo:lat>38.874979</geo:lat><geo:long>-77.114551</geo:long><entry>
  14.   <title>npm install cors</title>
  15.   <link href="" />
  16.   <updated>2014-05-09T00:00:00+00:00</updated>
  17.   <id></id>
  18.   <content type="html">&lt;p&gt;CORS is a popular node.js package I&amp;#39;ve written that provides an &lt;a href=""&gt;Express&lt;/a&gt; middleware you can use to enable &lt;a href=""&gt;CORS&lt;/a&gt; with various options. The code is open source (&lt;a href=""&gt;MIT License&lt;/a&gt;) and &lt;a href=""&gt;available on GitHub&lt;/a&gt;.&lt;/p&gt;
  20. &lt;h2&gt;Installation (via &lt;a href=""&gt;npm&lt;/a&gt;)&lt;/h2&gt;
  21. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;npm install cors
  22. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  23. &lt;h2&gt;Usage&lt;/h2&gt;
  25. &lt;h3&gt;Simple Usage (Enable &lt;em&gt;All&lt;/em&gt; CORS Requests)&lt;/h3&gt;
  26. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  27.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cors'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  28.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  30. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  31. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  33. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  34.  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'This is CORS-enabled for all origins!'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  35. &lt;span class="p"&gt;});&lt;/span&gt;
  37. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  38.  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'CORS-enabled web server listening on port 80'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  39. &lt;span class="p"&gt;});&lt;/span&gt;
  40. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  41. &lt;h3&gt;Enable CORS for a Single Route&lt;/h3&gt;
  42. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  43.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cors'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  44.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  46. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  47.  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'This is CORS-enabled for all origins!'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  48. &lt;span class="p"&gt;});&lt;/span&gt;
  50. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  51.  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'CORS-enabled web server listening on port 80'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  52. &lt;span class="p"&gt;});&lt;/span&gt;
  53. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  54. &lt;h3&gt;Configuring CORS&lt;/h3&gt;
  55. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  56.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cors'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  57.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  59. &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;corsOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  60.  &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
  61. &lt;span class="p"&gt;};&lt;/span&gt;
  63. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;corsOptions&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  64.  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'This is CORS-enabled for only'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  65. &lt;span class="p"&gt;});&lt;/span&gt;
  67. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  68.  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'CORS-enabled web server listening on port 80'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  69. &lt;span class="p"&gt;});&lt;/span&gt;
  70. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  71. &lt;h3&gt;Configuring CORS w/ Dynamic Origin&lt;/h3&gt;
  72. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  73.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cors'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  74.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  76. &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;whitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  77. &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;corsOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  78.  &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  79.    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;originIsWhitelisted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;whitelist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  80.    &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;originIsWhitelisted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  81.  &lt;span class="p"&gt;}&lt;/span&gt;
  82. &lt;span class="p"&gt;};&lt;/span&gt;
  84. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;corsOptions&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  85.  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'This is CORS-enabled for a whitelisted domain.'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  86. &lt;span class="p"&gt;});&lt;/span&gt;
  88. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  89.  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'CORS-enabled web server listening on port 80'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  90. &lt;span class="p"&gt;});&lt;/span&gt;
  91. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  92. &lt;h3&gt;Enabling CORS Pre-Flight&lt;/h3&gt;
  94. &lt;p&gt;Certain CORS requests are considered &amp;#39;complex&amp;#39; and require an initial
  95. &lt;code&gt;OPTIONS&lt;/code&gt; request (called the &amp;quot;pre-flight request&amp;quot;). An example of a
  96. &amp;#39;complex&amp;#39; CORS request is one that uses an HTTP verb other than
  97. GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable
  98. pre-flighting, you must add a new OPTIONS handler for the route you want
  99. to support:&lt;/p&gt;
  100. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  101.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cors'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  102.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  104. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// enable pre-flight request for DELETE request&lt;/span&gt;
  105. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  106.  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'This is CORS-enabled for all origins!'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  107. &lt;span class="p"&gt;});&lt;/span&gt;
  109. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  110.  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'CORS-enabled web server listening on port 80'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  111. &lt;span class="p"&gt;});&lt;/span&gt;
  112. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  113. &lt;p&gt;You can also enable pre-flight across-the-board like so:&lt;/p&gt;
  114. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-" data-lang=""&gt;app.options('*', cors()); // include before other routes
  115. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  116. &lt;h3&gt;Configuring CORS Asynchronously&lt;/h3&gt;
  117. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  118.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cors'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  119.  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  121. &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;whitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  122. &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;corsOptionsDelegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  123.  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;corsOptions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  124.  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;whitelist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Origin'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  125.    &lt;span class="nx"&gt;corsOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// reflect (enable) the requested origin in the CORS response&lt;/span&gt;
  126.  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  127.    &lt;span class="nx"&gt;corsOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// disable CORS for this request&lt;/span&gt;
  128.  &lt;span class="p"&gt;}&lt;/span&gt;
  129.  &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;corsOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// callback expects two parameters: error and options&lt;/span&gt;
  130. &lt;span class="p"&gt;};&lt;/span&gt;
  132. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/products/:id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;corsOptionsDelegate&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  133.  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'This is CORS-enabled for a whitelisted domain.'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  134. &lt;span class="p"&gt;});&lt;/span&gt;
  136. &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  137.  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'CORS-enabled web server listening on port 80'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  138. &lt;span class="p"&gt;});&lt;/span&gt;
  139. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  140. &lt;h2&gt;Configuration Options&lt;/h2&gt;
  142. &lt;ul&gt;
  143. &lt;li&gt;&lt;code&gt;origin&lt;/code&gt;: Configures the &lt;strong&gt;Access-Control-Allow-Origin&lt;/strong&gt; CORS header. Expects a string (ex: &amp;quot;;quot;). Set to &lt;code&gt;true&lt;/code&gt; to reflect the &lt;a href=""&gt;request origin&lt;/a&gt;, as defined by &lt;code&gt;req.header(&amp;#39;Origin&amp;#39;)&lt;/code&gt;. Set to &lt;code&gt;false&lt;/code&gt; to disable CORS. Can also be set to a function, which takes the request origin as the first parameter and a callback (which expects the signature &lt;code&gt;err [object], allow [bool]&lt;/code&gt;) as the second.&lt;/li&gt;
  144. &lt;li&gt;&lt;code&gt;methods&lt;/code&gt;: Configures the &lt;strong&gt;Access-Control-Allow-Methods&lt;/strong&gt; CORS header. Expects a comma-delimited string (ex: &amp;#39;GET,PUT,POST&amp;#39;) or an array (ex: &lt;code&gt;[&amp;#39;GET&amp;#39;, &amp;#39;PUT&amp;#39;, &amp;#39;POST&amp;#39;]&lt;/code&gt;).&lt;/li&gt;
  145. &lt;li&gt;&lt;code&gt;allowedHeaders&lt;/code&gt;: Configures the &lt;strong&gt;Access-Control-Allow-Headers&lt;/strong&gt; CORS header. Expects a comma-delimited string (ex: &amp;#39;Content-Type,Authorization&amp;#39;) or an array (ex: &lt;code&gt;[&amp;#39;Content-Type&amp;#39;, &amp;#39;Authorization]&lt;/code&gt;). If not specified, defaults to reflecting the headers specified in the request&amp;#39;s &lt;strong&gt;Access-Control-Request-Headers&lt;/strong&gt; header.&lt;/li&gt;
  146. &lt;li&gt;&lt;code&gt;exposedHeaders&lt;/code&gt;: Configures the &lt;strong&gt;Access-Control-Expose-Headers&lt;/strong&gt; CORS header. Expects a comma-delimited string (ex: &amp;#39;Content-Range,X-Content-Range&amp;#39;) or an array (ex: &lt;code&gt;[&amp;#39;Content-Range&amp;#39;, &amp;#39;X-Content-Range]&lt;/code&gt;). If not specified, no custom headers are exposed.&lt;/li&gt;
  147. &lt;li&gt;&lt;code&gt;credentials&lt;/code&gt;: Configures the &lt;strong&gt;Access-Control-Allow-Credentials&lt;/strong&gt; CORS header. Set to &lt;code&gt;true&lt;/code&gt; to pass the header, otherwise it is omitted.&lt;/li&gt;
  148. &lt;li&gt;&lt;code&gt;maxAge&lt;/code&gt;: Configures the &lt;strong&gt;Access-Control-Allow-Max-Age&lt;/strong&gt; CORS header. Set to an integer to pass the header, otherwise it is omitted.&lt;/li&gt;
  149. &lt;/ul&gt;
  151. &lt;p&gt;For details on the effect of each CORS header, &lt;a href=""&gt;read this article on HTML5 Rocks&lt;/a&gt;.&lt;/p&gt;
  153. &lt;h2&gt;Demo&lt;/h2&gt;
  155. &lt;p&gt;A demo that illustrates CORS working (and not working) using jQuery is available here: &lt;a href=""&gt;;/a&gt;&lt;/p&gt;
  157. &lt;p&gt;Code for that demo can be found here:&lt;/p&gt;
  159. &lt;ul&gt;
  160. &lt;li&gt;Client: &lt;a href=""&gt;;/a&gt;&lt;/li&gt;
  161. &lt;li&gt;Server: &lt;a href=""&gt;;/a&gt;&lt;/li&gt;
  162. &lt;/ul&gt;
  163. &lt;div class="feedflare"&gt;
  164. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  165. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  166. <feedburner:origLink></feedburner:origLink></entry>
  167. <entry>
  168.   <title>npm install require-directory</title>
  169.   <link href="" />
  170.   <updated>2012-12-16T00:00:00+00:00</updated>
  171.   <id></id>
  172.   <content type="html">&lt;p&gt;A common pattern I have found when building node.js applications
  173. revolves around how you refactor a large file into a directory of
  174. smaller files. For example, in an &lt;a href=""&gt;Express&lt;/a&gt; app
  175. you might start out defining routes in your &lt;em&gt;app.js&lt;/em&gt; file, but
  176. eventually migrate those routes into a &lt;em&gt;routes.js&lt;/em&gt; file that is then
  177. required into &lt;em&gt;app.js&lt;/em&gt;. What happens when &lt;em&gt;routes.js&lt;/em&gt; grows too large
  178. though? You chunk it up. You often end up with a &lt;em&gt;routes/&lt;/em&gt; directory,
  179. giving you a project structure that looks something like this:&lt;/p&gt;
  181. &lt;ul&gt;
  182. &lt;li&gt;app.js&lt;/li&gt;
  183. &lt;li&gt;routes/
  185. &lt;ul&gt;
  186. &lt;li&gt;auth.js&lt;/li&gt;
  187. &lt;li&gt;home.js&lt;/li&gt;
  188. &lt;li&gt;products.js&lt;/li&gt;
  189. &lt;/ul&gt;&lt;/li&gt;
  190. &lt;/ul&gt;
  192. &lt;p&gt;I also find it common to throw an &lt;em&gt;index.js&lt;/em&gt; file into that &lt;em&gt;routes/&lt;/em&gt;
  193. directory, which might look like:&lt;/p&gt;
  195. &lt;script src=""&gt; &lt;/script&gt;
  197. &lt;p&gt;Eventually you might find that &lt;em&gt;routes/auth.js&lt;/em&gt; has grown too large for
  198. one file as well, and you may refactor your files to look more like so:&lt;/p&gt;
  200. &lt;ul&gt;
  201. &lt;li&gt;app.js&lt;/li&gt;
  202. &lt;li&gt;routes/
  204. &lt;ul&gt;
  205. &lt;li&gt;auth/&lt;/li&gt;
  206. &lt;li&gt;login.js&lt;/li&gt;
  207. &lt;li&gt;logout.js&lt;/li&gt;
  208. &lt;li&gt;register.js&lt;/li&gt;
  209. &lt;li&gt;home.js&lt;/li&gt;
  210. &lt;li&gt;products.js&lt;/li&gt;
  211. &lt;/ul&gt;&lt;/li&gt;
  212. &lt;/ul&gt;
  214. &lt;p&gt;This changes your &lt;em&gt;routes/index.js&lt;/em&gt; file into:&lt;/p&gt;
  216. &lt;script src=""&gt; &lt;/script&gt;
  218. &lt;p&gt;... and so on and so forth. As node.js applications grow larger I see
  219. this pattern repeated over and over, often within the same application.
  220. To that end, I created &lt;strong&gt;require-directory&lt;/strong&gt; - an
  221. &lt;a href=""&gt;npm&lt;/a&gt; package that simplifies that &lt;em&gt;index.js&lt;/em&gt; file
  222. down into:&lt;/p&gt;
  224. &lt;script src=""&gt; &lt;/script&gt;
  226. &lt;p&gt;For more information, &lt;a href=""&gt;check out the package&amp;#39;s GitHub page.&lt;/a&gt;&lt;/p&gt;
  227. &lt;div class="feedflare"&gt;
  228. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  229. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  230. <feedburner:origLink></feedburner:origLink></entry>
  231. <entry>
  232.   <title>PagedList can haz HtmlHelperz?</title>
  233.   <link href="" />
  234.   <updated>2011-06-28T00:00:00+00:00</updated>
  235.   <id></id>
  236.   <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;
  238. &lt;p&gt;Back in March I made some modifications to the &lt;a href=""&gt;PagedList library&lt;/a&gt; I&amp;#39;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;
  240. &lt;h2&gt;Installation&lt;/h2&gt;
  242. &lt;p&gt;You can install via Nuget:&lt;/p&gt;
  243. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-bash" data-lang="bash"&gt;Install-Package PagedList
  244. Install-Package PagedList.Mvc
  245. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  246. &lt;p&gt;Alternatively, &lt;a href=""&gt;download the source&lt;/a&gt; straight from GitHub.&lt;/p&gt;
  248. &lt;h2&gt;What does PagedList do again?&lt;/h2&gt;
  250. &lt;p&gt;The first package contains the core PagedList library, which allows you to do this:&lt;/p&gt;
  252. &lt;script src=""&gt; &lt;/script&gt;
  254. &lt;h2&gt;Okay, so what is PagedList.Mvc then?&lt;/h2&gt;
  256. &lt;p&gt;The second package contains the new HTML Helper which lets you render pagers that look like this:&lt;/p&gt;
  258. &lt;p&gt;&lt;img src="/custom/files/old/DefaultPagingControlStyles.png" alt="IMAGE"&gt;&lt;/p&gt;
  260. &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;
  262. &lt;p&gt;You call the HTML Helper like so:&lt;/p&gt;
  264. &lt;script src=""&gt; &lt;/script&gt;
  266. &lt;h2&gt;Customizing the Rendering Options&lt;/h2&gt;
  268. &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;
  270. &lt;script src=""&gt; &lt;/script&gt;
  272. &lt;p&gt;For more information on the available rendering option settings, check &lt;a href=""&gt;PagedListRenderingOptions.cs&lt;/a&gt; on GitHub.&lt;/p&gt;
  273. &lt;div class="feedflare"&gt;
  274. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  275. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  276. <feedburner:origLink></feedburner:origLink></entry>
  277. <entry>
  278.   <title>Spearmen, Javelin Throwers, and the State Pattern. Oh My!</title>
  279.   <link href="" />
  280.   <updated>2009-08-15T00:00:00+00:00</updated>
  281.   <id></id>
  282.   <content type="html">&lt;p&gt;Last week one of Ayende/Oren&amp;#39;s posts caught my eye: &lt;a href=""&gt;Let the fighting commence!&lt;/a&gt; In it he discussed &lt;a href=""&gt;a blog post seen on Jamie Farser&amp;#39;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=""&gt;Everland&lt;/a&gt;. Since then I&amp;#39;ve been following Jamie&amp;#39;s progress (&lt;a href=""&gt;first try&lt;/a&gt;, &lt;a href=""&gt;further exploration&lt;/a&gt;, &lt;a href=""&gt;second try&lt;/a&gt;, &lt;a href=""&gt;third try&lt;/a&gt;, &lt;a href=""&gt;even further exploration&lt;/a&gt;) as he tries to take some of Ayende&amp;#39;s advice and implement the state pattern. Like Jamie, I am fairly new to the state pattern - sure I&amp;#39;ve read about it plenty (starting in &lt;a href=""&gt;Head First Design Patterns&lt;/a&gt; - a must have!), but I honestly have just never implemented it &amp;quot;for reals.&amp;quot; In my back &amp;amp; forth with Jamie I realized that it was time to put up or shut up - if I&amp;#39;m going to offer criticism I should also offer up an alternative solution.&lt;/p&gt;
  284. &lt;h2&gt;The Problem&lt;/h2&gt;
  286. &lt;p&gt;Let&amp;#39;s say we have a game where the board is made up of six-side polygons (&amp;quot;hexes&amp;quot;, 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&amp;#39;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;
  288. &lt;ul&gt;
  289. &lt;li&gt;The game engine doesn&amp;#39;t need to know specifics about each unit (such as range of attack).&lt;/li&gt;
  290. &lt;li&gt;A unit&amp;#39;s capabilities may change during the course of gameplay (such as a spearman being upgraded to a javelin thrower).&lt;/li&gt;
  291. &lt;/ul&gt;
  293. &lt;h2&gt;My Solution&lt;/h2&gt;
  295. &lt;p&gt;Before we look at the code, lets run through what is going to happen in-game.&lt;/p&gt;
  297. &lt;ol&gt;
  298. &lt;li&gt;The user selects one of their units, then selects an opposing unit somewhere else on the gameboard, then clicks an &amp;quot;Attack&amp;quot; button.&lt;/li&gt;
  299. &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;
  300. &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&amp;#39;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;
  301. &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&amp;#39; &lt;em&gt;Handle&lt;/em&gt; method uses &lt;a href=""&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;
  302. &lt;li&gt;Our &lt;strong&gt;Spearman&lt;/strong&gt; class&amp;#39; &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&amp;#39;t, a &lt;strong&gt;MovementCommand&lt;/strong&gt; is returned denoting which hex to move to.&lt;/li&gt;
  303. &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;
  304. &lt;/ol&gt;
  306. &lt;p&gt;Let&amp;#39;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&amp;#39;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;
  308. &lt;script src=""&gt; &lt;/script&gt;
  310. &lt;p&gt;Okay, easy enough. Moving on we can see the &lt;strong&gt;Unit&lt;/strong&gt; class&amp;#39; &lt;em&gt;ExecuteTurn&lt;/em&gt; method pass the context to its &lt;em&gt;CurrentState&lt;/em&gt; property&amp;#39;s &lt;em&gt;Handle&lt;/em&gt; method:&lt;/p&gt;
  312. &lt;script src=""&gt; &lt;/script&gt;
  314. &lt;p&gt;Our attacking unit&amp;#39;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&amp;#39;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;&amp;#39;s &lt;em&gt;Handle&lt;/em&gt; method):&lt;/p&gt;
  316. &lt;script src=""&gt; &lt;/script&gt;
  318. &lt;p&gt;The Spearman class&amp;#39; Handle method is then invoked:&lt;/p&gt;
  320. &lt;script src=""&gt; &lt;/script&gt;
  322. &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&amp;#39;ll see an example of a &lt;strong&gt;JavelinThrower&lt;/strong&gt; later. Finally we&amp;#39;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;
  324. &lt;script src=""&gt; &lt;/script&gt;
  326. &lt;p&gt;Before we move on, here is the promised &lt;strong&gt;JavelinThrower&lt;/strong&gt; class:&lt;/p&gt;
  328. &lt;script src=""&gt; &lt;/script&gt;
  330. &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=""&gt;strategy pattern&lt;/a&gt;.&lt;/p&gt;
  332. &lt;h2&gt;Prove It!&lt;/h2&gt;
  334. &lt;p&gt;So now that we&amp;#39;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;
  336. &lt;script src=""&gt; &lt;/script&gt;
  338. &lt;p&gt;And the results...&lt;/p&gt;
  340. &lt;p&gt;&lt;img src="/custom/files/old/Spearman-JavelinThrower-Tests-Passed.PNG" alt="IMAGE"&gt;&lt;/p&gt;
  342. &lt;p&gt;Yay!&lt;/p&gt;
  344. &lt;p&gt;So that is the road I went down, but what I really want to know is how would *you *solve this problem? If you&amp;#39;d like to take a deeper look at my code, download it and give it a try yourself:&lt;/p&gt;
  346. &lt;p&gt;&lt;a href="/custom/files/old/"&gt;;/a&gt;&lt;/p&gt;
  347. &lt;div class="feedflare"&gt;
  348. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  349. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  350. <feedburner:origLink></feedburner:origLink></entry>
  351. <entry>
  352.   <title>MVC Membership Starter Kit Released</title>
  353.   <link href="" />
  354.   <updated>2009-08-07T00:00:00+00:00</updated>
  355.   <id></id>
  356.   <content type="html">&lt;p class="warning"&gt;These instructions are out of date, and a newer version of the Membership Starter Kit is now available with support for ASP.NET MVC 4 and installation via NuGet. For more information, &lt;a href=""&gt;look the project up on GitHub&lt;/a&gt;.&lt;/p&gt;
  358. &lt;p&gt;Almost six months after the &lt;a href=""&gt;official release of Asp.Net MVC 1.0&lt;/a&gt; and nearly a year after &lt;a href="/2008/09/06/mvc-membership-preview-5/"&gt;the last release of the starter kit&lt;/a&gt;, I&amp;#39;ve finally rewritten and released the Asp.Net MVC Membership Starter Kit. If you&amp;#39;re already familiar with what it is and want to grab it, you can find the release on the &lt;a href=""&gt;GitHub project site&lt;/a&gt;.&lt;/p&gt;
  360. &lt;h2&gt;What is the Asp.Net MVC Membership Starter Kit?&lt;/h2&gt;
  362. &lt;p&gt;The starter kit currently consists of two things:&lt;/p&gt;
  364. &lt;ul&gt;
  365. &lt;li&gt;A sample website containing the controllers, models, and views needed to administer users &amp;amp; roles.&lt;/li&gt;
  366. &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;
  367. &lt;/ul&gt;
  369. &lt;h2&gt;How do I use it?&lt;/h2&gt;
  371. &lt;p&gt;In Asp.Net MVC 1 there isn&amp;#39;t a great story for packaging &amp;amp; sharing controllers, views, and other resources so we&amp;#39;ll need to follow a few manual steps:&lt;/p&gt;
  373. &lt;ul&gt;
  374. &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;
  375. &lt;li&gt;Grab the &lt;strong&gt;MvcMembership.dll&lt;/strong&gt; assembly and place it wherever you&amp;#39;re including external libraries in your project. Add a reference to the assembly to your Asp.Net MVC application.&lt;/li&gt;
  376. &lt;li&gt;Copy the &lt;strong&gt;UserAdministrationController.cs&lt;/strong&gt; file from the &lt;em&gt;SampleWebsite&lt;/em&gt;&amp;#39;s &lt;em&gt;Controllers&lt;/em&gt; directory to your app&amp;#39;s &lt;em&gt;Controllers&lt;/em&gt; directory.&lt;/li&gt;
  377. &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;&amp;#39;s &lt;em&gt;Models *folder to your app&amp;#39;s *Models&lt;/em&gt; folder.&lt;/li&gt;
  378. &lt;li&gt;Copy the &lt;strong&gt;UserAdministration&lt;/strong&gt; folder from the &lt;em&gt;SampleWebsite&lt;/em&gt;&amp;#39;s &lt;em&gt;Views&lt;/em&gt; folder to your app&amp;#39;s &lt;em&gt;Views&lt;/em&gt; folder.&lt;/li&gt;
  379. &lt;li&gt;Make sure you&amp;#39;ve configured your &lt;strong&gt;web.config&lt;/strong&gt; properly for Membership and Roles. If you aren&amp;#39;t sure of how to do this, take a look at the first two articles in &lt;a href=""&gt;this series by Scott Mitchell at 4GuysFromRolla&lt;/a&gt;.&lt;/li&gt;
  380. &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&amp;#39;s last activity date:&lt;/li&gt;
  381. &lt;/ul&gt;
  383. &lt;script src=""&gt; &lt;/script&gt;
  385. &lt;h2&gt;What is new since the last release?&lt;/h2&gt;
  387. &lt;p&gt;Well, the last release was for &lt;a href=""&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;
  389. &lt;ul&gt;
  390. &lt;li&gt;The &lt;a href=""&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;
  391. &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;
  392. &lt;/ul&gt;
  394. &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&amp;#39;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=""&gt;authenticating via RPX in MVC&lt;/a&gt;.&lt;/p&gt;
  396. &lt;h2&gt;What comes next?&lt;/h2&gt;
  398. &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=""&gt;&amp;quot;area&amp;quot; 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&amp;#39;m glad to see the blue badges are going to provide a common solution. Along with that I&amp;#39;ll likely try to add RPX authentication ala Maarten&amp;#39;s post.&lt;/p&gt;
  399. &lt;div class="feedflare"&gt;
  400. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  401. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  402. <feedburner:origLink></feedburner:origLink></entry>
  403. <entry>
  404.   <title>Return of the PagedList</title>
  405.   <link href="" />
  406.   <updated>2009-06-15T00:00:00+00:00</updated>
  407.   <id></id>
  408.   <content type="html">&lt;p class="warning"&gt;I recommend grabbing the latest code from NuGet or directly from &lt;a href=""&gt;the project's site on GitHub&lt;/a&gt;. The CodePlex project is no longer maintained.&lt;/p&gt;
  410. &lt;p&gt;It has been nearly a year since I &lt;a href="/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=""&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;
  412. &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=""&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&amp;#39;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;
  414. &lt;ul&gt;
  415. &lt;li&gt;The source is now available on CodePlex: &lt;a href=""&gt;;/a&gt;. This should make finding and downloading the code easier than finding the correct blog entry on some dude&amp;#39;s blog.&lt;/li&gt;
  416. &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&amp;#39;s taxonomy.&lt;/li&gt;
  417. &lt;li&gt;Further incremental changes can be found in the Change Log on the CodePlex project site.&lt;/li&gt;
  418. &lt;/ul&gt;
  419. &lt;div class="feedflare"&gt;
  420. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  421. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  422. <feedburner:origLink></feedburner:origLink></entry>
  423. <entry>
  424.   <title>Creating an MVC Project in Visual Studio 2010</title>
  425.   <link href="" />
  426.   <updated>2009-06-09T00:00:00+00:00</updated>
  427.   <id></id>
  428.   <content type="html">&lt;p class="warning"&gt;These instructions are not necessary with the RTM version of Visual Studio 2010 or later releases of Visual Studio.&lt;/p&gt;
  430. &lt;p&gt;Earlier today &lt;a href=""&gt;Phil Haack announced&lt;/a&gt; that the Asp.Net MVC installer for Visual Studio 2010 Beta 1 is &lt;a href=""&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&amp;#39;m happy to say that the basic experience went flawlessly for me, though it appears &lt;a href=""&gt;that may not hold true for everyone&lt;/a&gt;.&lt;/p&gt;
  432. &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=";amp;displaylang=en"&gt;full install 2 ISO download (1.1 GB)&lt;/a&gt; or a &lt;a href=";amp;displaylang=en"&gt;lightweight (5 MB) &amp;quot;web install&amp;quot; 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&amp;#39;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;
  434. &lt;p&gt;Once Visual Studio has finished installing, download and install the &lt;a href=""&gt;ASP.NET MVC 1.1 Installer for Visual Studio 2010 from CodePlex&lt;/a&gt;. While you&amp;#39;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: unzip &amp;quot;ASP.NET MVC;quot; into &amp;quot;C:\Users&amp;amp;lt;username&amp;gt;\Documents\Visual Studio 10\Code Snippets\Visual Web Developer\My HTML Snippets&amp;quot;, where &amp;quot;C:\&amp;quot; is your OS drive.&lt;/p&gt;
  436. &lt;p&gt;If you encounter any difficulties with the installer, check out this &lt;a href=""&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;
  438. &lt;p&gt;&lt;img src="/custom/files/old/1-vs2010-first-boot-1024x736.jpg" alt="IMAGE"&gt;
  439. &lt;img src="/custom/files/old/2-creating-mvc-project-150x150.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  441. &lt;p&gt;From here, you can launch the new New Project dialog either via the File menu or by clicking &amp;quot;Projects&amp;quot; on the left side of the startup screen and then clicking the &amp;quot;New Project&amp;quot; icon. If the Asp.Net MVC 1.1 installer has been correctly installed, you will find a &amp;quot;ASP.NET MVC Web Application&amp;quot; entry under the &amp;quot;Web&amp;quot; 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;
  443. &lt;p&gt;&lt;img src="/custom/files/old/3-create-test-project-150x150.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  445. &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 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&amp;#39;t a big deal, as I prefer to setup my test projects manually and don&amp;#39;t see a lot of value in the dialog, but I&amp;#39;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;
  447. &lt;p&gt;&lt;img src="/custom/files/old/4-project-created-1024x736.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  449. &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=""&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 &amp;quot;Tools&amp;quot; &amp;gt; &amp;quot;Import and Export Settings...&amp;quot; allowed me to import the defaults, thus making my color scheme readable, if a bit too vanilla.&lt;/p&gt;
  451. &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&amp;#39;s Controllers folder and select &amp;quot;Add &amp;gt; Controller...&amp;quot;. 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 &amp;quot;Add View...&amp;quot;. I was pleased to find that neither of these features had been lost and were working as expected.&lt;/p&gt;
  453. &lt;p&gt;&lt;img src="/custom/files/old/9-choosing-actionlink-snippet-300x206.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  455. &lt;p&gt;So now I&amp;#39;ve created a ProductController with various actions as well as a basic view for the controller&amp;#39;s Index action, but I don&amp;#39;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&amp;#39;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 &amp;quot;Insert Snippet...&amp;quot; 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 &amp;quot;My HTML Snippets&amp;quot; folder. Selecting that folder presents you with a list of many basic HTML helper snippets.&lt;/p&gt;
  457. &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&amp;#39;s text and action also as I would expect. I did notice that the snippet doesn&amp;#39;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;
  459. &lt;p&gt;With that done I hit F5 and was able to browse to my Product controller&amp;#39;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&amp;#39;s integration should be quite good. &lt;/p&gt;
  460. &lt;div class="feedflare"&gt;
  461. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  462. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  463. <feedburner:origLink></feedburner:origLink></entry>
  464. <entry>
  465.   <title>DevPocalypse : A *Basic* Asp.Net MVC + jQuery Game</title>
  466.   <link href="" />
  467.   <updated>2008-12-12T00:00:00+00:00</updated>
  468.   <id></id>
  469.   <content type="html">&lt;p&gt;Last weekend I had the privilege of speaking at the second &lt;a href=""&gt;Northern Virginia CodeCamp&lt;/a&gt; of the year, thanks to an invitation from &lt;a href=""&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=""&gt;fill out an eval&lt;/a&gt;! For those of you who didn&amp;#39;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 &amp;amp; posted below.&lt;/p&gt;
  471. &lt;h2&gt;DevPocalypse (ASP.NET MVC + jQuery = Simple Multiplayer Action)&lt;/h2&gt;
  473. &lt;p&gt;The basic idea of the game is that multiple players can exist on a grid (a &amp;quot;screen&amp;quot;) and move around to unoccupied spaces (&amp;quot;blocks&amp;quot;) 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;
  475. &lt;p&gt;Let&amp;#39;s take a gander at what the app looks like when it is running:&lt;/p&gt;
  477. &lt;p&gt;&lt;img src="/custom/files/old/DevPocalypse-Screenshot_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  479. &lt;p&gt;Yup, like I said: basic. So those two little guys are players. You can&amp;#39;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;
  481. &lt;script src=""&gt; &lt;/script&gt;
  483. &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;
  485. &lt;script src=""&gt; &lt;/script&gt;
  487. &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;strong&gt;&lt;em&gt;id&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;c&lt;/em&gt;&lt;/strong&gt; variables):&lt;/p&gt;
  489. &lt;script src=""&gt; &lt;/script&gt;
  491. &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;
  493. &lt;p&gt;Thanks, and I hope to see you at the next CodeCamp!&lt;/p&gt;
  495. &lt;p&gt;&lt;a href="/custom/files/old/"&gt;;/a&gt;&lt;/p&gt;
  496. &lt;div class="feedflare"&gt;
  497. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  498. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  499. <feedburner:origLink></feedburner:origLink></entry>
  500. <entry>
  501.   <title>MVC/jQuery Presentation at NoVa CodeCamp - Dec. 6</title>
  502.   <link href="" />
  503.   <updated>2008-11-24T00:00:00+00:00</updated>
  504.   <id></id>
  505.   <content type="html">&lt;p&gt;&lt;img src="/custom/files/old/NoVaCodeCamp.gif" alt="IMAGE"&gt;&lt;/p&gt;
  507. &lt;p&gt;&lt;a href=""&gt;Jeff Schoolcraft&lt;/a&gt; was kind enough to ask me to speak at this year&amp;#39;s second &lt;a href=""&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=";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&amp;#39;re interested in attending, please make sure you &lt;a href=""&gt;register&lt;/a&gt; soon!&lt;/p&gt;
  509. &lt;p&gt;I don&amp;#39;t yet have word on the final presentation schedule, but here is the abstract for the presentation I will be giving:&lt;/p&gt;
  511. &lt;blockquote&gt;
  512. **Creating an AJAX MMORPG With jQuery &amp; Asp.Net MVC**
  514. 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!
  515. &lt;/blockquote&gt;
  517. &lt;p&gt;In the following two weeks I&amp;#39;ll be posting the code I&amp;#39;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;
  518. &lt;div class="feedflare"&gt;
  519. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  520. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  521. <feedburner:origLink></feedburner:origLink></entry>
  522. <entry>
  523.   <title>My PDC 2008 Agenda</title>
  524.   <link href="" />
  525.   <updated>2008-10-23T00:00:00+00:00</updated>
  526.   <id></id>
  527.   <content type="html">&lt;p&gt;This Saturday I&amp;#39;ll be headed off to sunny Los Angeles for Microsoft&amp;#39;s &lt;a href=""&gt;Professional Developer Conference 2008&lt;/a&gt;. This is the first time I&amp;#39;ve gone and I&amp;#39;m really looking forward to it. I&amp;#39;m staying at &lt;a href=""&gt;Hotel Figeuroa&lt;/a&gt;, only a couple blocks from the &lt;a href=""&gt;Los Angeles Convention Center&lt;/a&gt;, and I&amp;#39;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:[email protected]"&gt;drop me an email&lt;/a&gt;.&lt;/p&gt;
  529. &lt;h2&gt;Pre-Conference / Sunday Oct 26 2008&lt;/h2&gt;
  531. &lt;ul&gt;
  532. &lt;li&gt;&lt;strong&gt;10:00 AM - 5:45 PM:&lt;/strong&gt; &lt;a href=""&gt;Creating Rich Internet Applications with Silverlight&lt;/a&gt;&lt;/li&gt;
  533. &lt;/ul&gt;
  535. &lt;h2&gt;Day One / Monday Oct 27 2008&lt;/h2&gt;
  537. &lt;ul&gt;
  538. &lt;li&gt;&lt;strong&gt;8:30 AM - 11:00 AM:&lt;/strong&gt; Keynote&lt;/li&gt;
  539. &lt;li&gt;&lt;strong&gt;11:00 AM - 12:45 AM:&lt;/strong&gt; &lt;a href=""&gt;A Lap Around Cloud Services (Part 1)&lt;/a&gt;&lt;/li&gt;
  540. &lt;li&gt;&lt;strong&gt;12:45 PM - 1:45 PM:&lt;/strong&gt; &lt;a href=""&gt;Microsoft Expression Blend: Tips &amp;amp; Tricks&lt;/a&gt;&lt;/li&gt;
  541. &lt;li&gt;&lt;strong&gt;1:45 PM - 3:30 PM:&lt;/strong&gt; &lt;a href=""&gt;ASP.Net 4.0 Roadmap&lt;/a&gt;&lt;/li&gt;
  542. &lt;li&gt;&lt;strong&gt;3:30 PM - 5:15 PM:&lt;/strong&gt; &lt;a href=""&gt;A Lap Around Cloud Services (Part 2)&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href=""&gt;ASP.NET MVC: A New Framework for Building Web Applications&lt;/a&gt;&lt;/li&gt;
  543. &lt;li&gt;&lt;strong&gt;5:15 PM - 6:30 PM:&lt;/strong&gt; &lt;a href=""&gt;Developing and Deploying Your First Cloud Service&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href=""&gt;Microsoft .NET Framework: Overview and Applications for Babies&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href=""&gt;Windows Workflow Foundation 4.0: A First Look&lt;/a&gt;&lt;/li&gt;
  544. &lt;/ul&gt;
  546. &lt;h2&gt;Day Two / Tuesday Oct 28 2008&lt;/h2&gt;
  548. &lt;ul&gt;
  549. &lt;li&gt;&lt;strong&gt;3:30 AM - 12:45 PM:&lt;/strong&gt; Keynote&lt;/li&gt;
  550. &lt;li&gt;&lt;strong&gt;12:45 PM - 1:45 PM:&lt;/strong&gt; &lt;a href=""&gt;Windows 7: Welcome to the Windows 7 Desktop&lt;/a&gt;&lt;/li&gt;
  551. &lt;li&gt;&lt;strong&gt;1:45 PM - 3:30 PM:&lt;/strong&gt; &lt;a href=""&gt;Essential Cloud Storage Services&lt;/a&gt;&lt;/li&gt;
  552. &lt;li&gt;&lt;strong&gt;3:30 PM - 5:15 PM:&lt;/strong&gt; &lt;a href=""&gt;Microsoft Visual Studio: Easing ASP.NET Web Deployment&lt;/a&gt;&lt;/li&gt;
  553. &lt;li&gt;&lt;strong&gt;5:15 PM - 6:30 PM:&lt;/strong&gt; &lt;a href=""&gt;Entity Framework Futures&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href=""&gt;ASP.NET and JQuery&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href=""&gt;Architecting Services for the Cloud&lt;/a&gt;&lt;/li&gt;
  554. &lt;/ul&gt;
  556. &lt;h2&gt;Day Three / Wednesday Oct 29 2008&lt;/h2&gt;
  558. &lt;ul&gt;
  559. &lt;li&gt;&lt;strong&gt;8:30 AM - 10:30 AM:&lt;/strong&gt; Keynote&lt;/li&gt;
  560. &lt;li&gt;&lt;strong&gt;10:30 AM - 12:00 PM:&lt;/strong&gt; &lt;a href=""&gt;WCF 4.0: Building WCF Services with WF in Microsoft .NET 4.0&lt;/a&gt;&lt;/li&gt;
  561. &lt;li&gt;&lt;strong&gt;12:00 PM - 1:15 PM:&lt;/strong&gt; &lt;a href=""&gt;Microsoft XNA Game Studio: An Overview&lt;/a&gt;&lt;/li&gt;
  562. &lt;li&gt;&lt;strong&gt;1:15 PM - 3:00 PM:&lt;/strong&gt; &lt;a href=""&gt;&amp;quot;Oslo&amp;quot;: Customizing and Extending the Visual Design Experience&lt;/a&gt;&lt;/li&gt;
  563. &lt;li&gt;&lt;strong&gt;3:00 PM - 4:45 PM:&lt;/strong&gt; &lt;a href=""&gt;A Day in the Life of a Cloud Service Developer&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href=""&gt;Oomph: A Microformat Toolkit&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href=""&gt;&amp;quot;Oslo&amp;quot;: Repository and Models&lt;/a&gt;&lt;/li&gt;
  564. &lt;li&gt;&lt;strong&gt;4:45 PM - 6:00 PM:&lt;/strong&gt; &lt;a href=""&gt;A Lap around &amp;quot;Oslo&amp;quot;&lt;/a&gt;&lt;/li&gt;
  565. &lt;/ul&gt;
  567. &lt;h2&gt;Day Four / Thursday Oct 30 2008&lt;/h2&gt;
  569. &lt;ul&gt;
  570. &lt;li&gt;&lt;strong&gt;8:30 AM - 10:15 AM:&lt;/strong&gt; &lt;a href=""&gt;WCF: Developing RESTful Services&lt;/a&gt;&lt;/li&gt;
  571. &lt;li&gt;&lt;strong&gt;10:15 AM - 12:00 PM:&lt;/strong&gt; &lt;a href=""&gt;Services Symposium: Enterprise Grade Cloud Applications&lt;/a&gt;&lt;/li&gt;
  572. &lt;li&gt;&lt;strong&gt;12:00 PM - 1:45 PM:&lt;/strong&gt; &lt;a href=""&gt;Cloud Computing: Programming in the Cloud&lt;/a&gt;&lt;/li&gt;
  573. &lt;li&gt;&lt;strong&gt;1:45 PM - 3:00 PM:&lt;/strong&gt; &lt;a href=""&gt;ASP.NET AJAX Futures&lt;/a&gt; &lt;em&gt;or&lt;/em&gt; &lt;a href=""&gt;Workflow Services: Orchestrating Services and Business Processes Using Cloud-Based Workflow&lt;/a&gt;&lt;/li&gt;
  574. &lt;/ul&gt;
  575. &lt;div class="feedflare"&gt;
  576. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  577. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  578. <feedburner:origLink></feedburner:origLink></entry>
  579. <entry>
  580.   <title>ASP.Net MVC Goes Beta!</title>
  581.   <link href="" />
  582.   <updated>2008-10-16T00:00:00+00:00</updated>
  583.   <id></id>
  584.   <content type="html">&lt;p&gt;I discovered via &lt;a href=""&gt;DotNetKicks&lt;/a&gt; this afternoon that the ASP.Net MVC framework&amp;#39;s beta release is now &lt;a href=";amp;displaylang=en&amp;amp;tm"&gt;available for download from;/a&gt;. No release or source code is yet available from the &lt;a href=""&gt;CodePlex project&lt;/a&gt;, but I expect we&amp;#39;ll see it there soon enough. Congratulations to the team at Microsoft, RTM is knocking at the door!&lt;/p&gt;
  586. &lt;p&gt;&lt;a href=";amp;displaylang=en&amp;amp;tm"&gt;Download ASP.NET MVC Beta.&lt;/a&gt;&lt;/p&gt;
  587. &lt;div class="feedflare"&gt;
  588. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  589. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  590. <feedburner:origLink></feedburner:origLink></entry>
  591. <entry>
  592.   <title>Introduction to ASP.Net MVC for Alt.Net DC Tonight</title>
  593.   <link href="" />
  594.   <updated>2008-09-24T00:00:00+00:00</updated>
  595.   <id></id>
  596.   <content type="html">&lt;p&gt;Anyone in the Washington, DC area who is interested in an introductory peek at Microsoft&amp;#39;s new ASP.Net MVC platform is invited to come out to tonight&amp;#39;s Alt.Net meeting. I will be presenting the front-to-back basics you need to know to get started in developing with the MVC framework, using a MVC blog engine as our use case. Details about the when/where below. Many thanks to Matthew Podwysocki for asking me to speak tonight; it is a great privilege.&lt;/p&gt;
  598. &lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt;&lt;/p&gt;
  600. &lt;p&gt;September 24, 2008 - 7PM to 9PM&lt;/p&gt;
  602. &lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt;&lt;/p&gt;
  604. &lt;p&gt;&lt;a href=""&gt;Cynergy Systems Inc.&lt;/a&gt;&lt;br&gt;
  605. 1600 K St NW&lt;br&gt;
  606. Suite 300&lt;br&gt;
  607. Washington, DC 20006&lt;/p&gt;
  609. &lt;p&gt;&lt;a href=";amp;hl=en&amp;amp;geocode=&amp;amp;q=1600+K+St+NW,+Washington,+DC+20006&amp;amp;sll=38.880459,-77.109452&amp;amp;sspn=0.012444,0.027895&amp;amp;ie=UTF8&amp;amp;z=16"&gt;Show in Google Maps.&lt;/a&gt;&lt;/p&gt;
  611. &lt;p&gt;&lt;strong&gt;More Info:&lt;/strong&gt;&lt;/p&gt;
  613. &lt;p&gt;&lt;a href=""&gt;Matthew Podwysocki&amp;#39;s blog post&lt;/a&gt;&lt;/p&gt;
  614. &lt;div class="feedflare"&gt;
  615. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  616. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  617. <feedburner:origLink></feedburner:origLink></entry>
  618. <entry>
  619.   <title>Introduction to ASP.Net MVC for Alt.Net DC - Presentation Materials</title>
  620.   <link href="" />
  621.   <updated>2008-09-24T00:00:00+00:00</updated>
  622.   <id></id>
  623.   <content type="html">&lt;p&gt;I just got back from my ASP.Net MVC Presentation for tonight&amp;#39;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&amp;#39;t hesitate to &lt;a href="mailto:[email protected]"&gt;email me&lt;/a&gt; if you have any questions. Also I owe a big thanks to &lt;a href=""&gt;Matthew Podwysocki&lt;/a&gt; for inviting me to speak. Thanks Matt, I really enjoyed the opportunity.&lt;/p&gt;
  625. &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;/p&gt;
  627. &lt;ul&gt;
  628. &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;
  629. &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;
  630. &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&amp;#39;ll find the code we wrote tonight.&lt;/li&gt;
  631. &lt;/ul&gt;
  633. &lt;p&gt;If you want to run the project, make sure you have SQL Server Express installed and create a database named &amp;quot;MvcTutorial-Blog&amp;quot;. Afterward you can run the &amp;quot;MvcTutorials.Blog.Domain.Bootstrap&amp;quot; project to insert test data and run the website project.&lt;/p&gt;
  635. &lt;p&gt;Be sure to let me know if there are any questions or comments about tonight&amp;#39;s presentation or this post&amp;#39;s code!&lt;/p&gt;
  637. &lt;p&gt;&lt;a href="/custom/files/old/"&gt;;/a&gt;&lt;/p&gt;
  638. &lt;div class="feedflare"&gt;
  639. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  640. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  641. <feedburner:origLink></feedburner:origLink></entry>
  642. <entry>
  643.   <title>MVC Membership - Preview 5</title>
  644.   <link href="" />
  645.   <updated>2008-09-06T00:00:00+00:00</updated>
  646.   <id></id>
  647.   <content type="html">&lt;p class="warning"&gt;This post is out of date. Please reference this project's &lt;a href=""&gt;GitHub page&lt;/a&gt; for the latest code.&lt;/p&gt;
  649. &lt;p&gt;Last weekend I posted a release of the MVC Membership Starter Kit that targets &lt;a href=""&gt;Preview 5 of the ASP.Net MVC framework&lt;/a&gt;. There was no packaged release targeting &lt;a href=""&gt;Preview 4&lt;/a&gt; (though if you &lt;a href=""&gt;downloaded the latest source&lt;/a&gt;, it worked), so this release essentially packages the changes from both previews.&lt;/p&gt;
  651. &lt;h2&gt;Why does the MVC Membership Starter Kit still exist?&lt;/h2&gt;
  653. &lt;p&gt;The biggest change affecting the MVC Membership Starter Kit is that the default ASP.Net MVC Web Application project includes &lt;a href=""&gt;login/logout, register, and change password functionality as of Preview 4&lt;/a&gt;. This is great and I&amp;#39;m glad to see them do it. It is my hope they will eventually include membership administration functionality as well. For now, however, they haven&amp;#39;t included it. This leaves three main features that are now driving the existence of this project:&lt;/p&gt;
  655. &lt;ul&gt;
  656. &lt;li&gt;&lt;strong&gt;Membership Administration:&lt;/strong&gt; What good is registration, login, and logout if a site&amp;#39;s owner cannot change a user&amp;#39;s roles or manage their user base? While Visual Studio&amp;#39;s &lt;a href=""&gt;Web Site Administration Tool&lt;/a&gt; covers most of your bases during development, it isn&amp;#39;t a real option for use by web site administrators in a production application.&lt;/li&gt;
  657. &lt;li&gt;&lt;strong&gt;OpenID Integration:&lt;/strong&gt; Preview 4&amp;#39;s built-in login functionality only covers the use of standard username/password authentication. It seems likely that this will continue, as I am not aware of any plans for official &lt;a href=""&gt;OpenID&lt;/a&gt; support within the .Net framework. We are using &lt;a href=""&gt;Andrew Arnott &amp;amp; co&amp;#39;s DotNetOpenId&lt;/a&gt; project to help you let your users log in using OpenID.&lt;/li&gt;
  658. &lt;li&gt;&lt;strong&gt;WindowsLive LiveID Integration:&lt;/strong&gt; &lt;a href=""&gt;Maarten&lt;/a&gt;&amp;#39;s &lt;a href=""&gt;LiveID&lt;/a&gt; integration has unfortunately not made this release. I anticipate that it will be available again for the next release, which will target &lt;a href=""&gt;the first beta release of ASP.Net MVC&lt;/a&gt;.&lt;/li&gt;
  659. &lt;/ul&gt;
  661. &lt;h2&gt;What has changed?&lt;/h2&gt;
  663. &lt;ul&gt;
  664. &lt;li&gt;&lt;strong&gt;No more login/logout/password retrieval.&lt;/strong&gt; Because the AccountController and its views are now included by default in new projects, the need for this functionality has gone away.&lt;/li&gt;
  665. &lt;li&gt;&lt;strong&gt;Less assemblies to reference.&lt;/strong&gt; Rather than the MembershipAdministrationController and other code being compiled into a separate assembly that you must include, you now drop the controllers directly into your web app. This allows you to easily change the code as your project evolves. The starter kit&amp;#39;s implementation is really just a starting point that you can build off of.&lt;/li&gt;
  666. &lt;li&gt;&lt;strong&gt;Controllers are split.&lt;/strong&gt; In previous releases the OpenID and WindowsLive login functionality was included in the MembershipAuthenticationController. The OpenID functionality has since been moved into a separate controller with separate views. This was done because (a) the MembershipAuthenticationController no longer exists and (b) moving forward more of the pieces of this kit will be separated from each other so that you can include them a la carte.&lt;/li&gt;
  667. &lt;/ul&gt;
  669. &lt;h2&gt;Download&lt;/h2&gt;
  671. &lt;p&gt;You can download the Preview 5 release of the MVC Membership Starter Kit from CodePlex:&lt;/p&gt;
  673. &lt;p&gt;&lt;a href=""&gt;;/a&gt;&lt;/p&gt;
  674. &lt;div class="feedflare"&gt;
  675. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  676. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  677. <feedburner:origLink></feedburner:origLink></entry>
  678. <entry>
  679.   <title>PagedList Strikes Back</title>
  680.   <link href="" />
  681.   <updated>2008-07-08T00:00:00+00:00</updated>
  682.   <id></id>
  683.   <content type="html">&lt;p class="warning"&gt;There is an updated version of the PagedList&amp;lt;T&amp;gt; code available &lt;a href=""&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;
  685. &lt;p&gt;A few months ago I posted about &lt;a href="/2008/04/08/updated-pagedlist-class/"&gt;my changes&lt;/a&gt; to &lt;a href=""&gt;Rob Conery&amp;#39;s PagedList&lt;/a&gt; class. Since writing that article many comments have been left about how to further improve the design, which I have since incorporated into a new, further improved PagedList class. For those who aren&amp;#39;t familiar, the PagedList class allows scenarios such as the following:&lt;/p&gt;
  687. &lt;script src=""&gt; &lt;/script&gt;
  689. &lt;p&gt;So in the above scenario (an example MVC action), if you had a list of 30 products with IDs 1-30 and passed in a pageIndex of 2 you would pass the products with IDs 21-30 into your view. Best of all it uses IQueryable, so if you pass a LINQ expression or IQueryable result into ToPagedList(...) it will do the filtering on the database side! Take a look at the new improved PagedList &lt;a href=""&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;
  691. &lt;p&gt;&lt;strong&gt;Changes Since Previous Version:&lt;/strong&gt;&lt;/p&gt;
  693. &lt;ul&gt;
  694. &lt;li&gt;&lt;strong&gt;Changed &amp;quot;TotalPages&amp;quot; property to &amp;quot;PageCount&amp;quot;.&lt;/strong&gt; This was done to more clearly illustrate the purpose of this property (more in line with the standard List&amp;lt;T&amp;gt; .Count property).&lt;/li&gt;
  695. &lt;li&gt;&lt;strong&gt;Changed &amp;quot;TotalCount&amp;quot; property to &amp;quot;TotalItemCount&amp;quot;.&lt;/strong&gt; This was done to differentiate between Pages and Items more clearly.&lt;/li&gt;
  696. &lt;li&gt;&lt;strong&gt;Switched &amp;quot;PageIndex&amp;quot; back to being a zero-based index, rather than one-based.&lt;/strong&gt; The PageIndex was set to be one-based because the most common use-case that I could think of, outputting a pager (i.e.: Previous - 1 - 2 - 3 - Next), was one-based and it would be nice to not have to do &amp;quot;obj.PageIndex + 1&amp;quot; everywhere. This was probably a poor decision. Some people found it confusing and &lt;a href="/2008/04/08/updated-pagedlist-class/#comment-152106122"&gt;others found that it didn&amp;#39;t work with the standard .Net DataPager&lt;/a&gt;.&lt;/li&gt;
  697. &lt;li&gt;&lt;strong&gt;Added &amp;quot;PageNumber&amp;quot; property.&lt;/strong&gt; As suggested &lt;a href="/2008/04/08/updated-pagedlist-class/#comment-152106104"&gt;via comment&lt;/a&gt; on my previous post, PageNumber is just PageIndex + 1.&lt;/li&gt;
  698. &lt;li&gt;&lt;strong&gt;Treat all data as IQueryable for the duration of class initialization.&lt;/strong&gt; Tgmdbm, a frequent contributer on the &lt;a href=""&gt;ASP.Net MVC forums&lt;/a&gt;, pointed out &lt;a href="/2008/04/08/updated-pagedlist-class/#comment-152106101"&gt;some good reasons&lt;/a&gt; why everything should be treated as IQueryable before the .Skip(x).Take(y). I&amp;#39;m not 100% sold that treating it as IEnumerable would also work for IQueryable objects (since IQueryable supports IEnumerable), but to be safe I have defaulted everything to using IQueryable. You can still pass in a strict IEnumerable, but it will be converted to IQueryable for the duration of the PagedList class initialization process.&lt;/li&gt;
  699. &lt;li&gt;&lt;strong&gt;Tested with &lt;a href=""&gt;;/a&gt;.&lt;/strong&gt; While the PagedList class isn&amp;#39;t exactly rocket science, I want to strive to improve the quality of the code that I&amp;#39;m presenting to the community. I also enjoyed having an excuse to try out xUnit&amp;#39;s data-driven testing using the [Theory] attribute (similar to MbUnit&amp;#39;s [RowTest]) for the first time. Not much has been written about it, but I was able to find &lt;a href=""&gt;some examples from Ben Hall&lt;/a&gt; which got me up and testing quickly.&lt;/li&gt;
  700. &lt;/ul&gt;
  702. &lt;p&gt;A big thanks to everyone who has thrown their two cents in to help improve this small but useful class!&lt;/p&gt;
  703. &lt;div class="feedflare"&gt;
  704. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  705. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  706. <feedburner:origLink></feedburner:origLink></entry>
  707. <entry>
  708.   <title>MVC Controller Action Security Hole</title>
  709.   <link href="" />
  710.   <updated>2008-07-08T00:00:00+00:00</updated>
  711.   <id></id>
  712.   <content type="html">&lt;p&gt;The latest of &lt;a href=""&gt;Stephen Walther&lt;/a&gt;&amp;#39;s invaluable &lt;a href=""&gt;ASP.Net MVC Tip series&lt;/a&gt; points out a MVC scenario that was previously unknown to me: &lt;a href=""&gt;passing cookies and server variables into controllers as action parameters&lt;/a&gt;. While the idea is neat, &lt;a href=""&gt;a comment left by Francois Ward&lt;/a&gt; echoed my immediate skepticism over whether this could be safe. After playing around I believe I have confirmed my suspicions that making use of this capability is a Very Bad Idea.&lt;/p&gt;
  714. &lt;p&gt;I&amp;#39;ll let Francois&amp;#39; comment explain the problem (emphasis mine):&lt;/p&gt;
  716. &lt;blockquote&gt;
  717. Tuesday, July 08, 2008 4:16 PM by Francois Ward
  719. Hmm, I didn't look into it much, but is that -safe-? I mean, if the variables in the index function are filled up automatically... it would be ok if it was only one type (all cookies, or all server variables), but since you can mix and match, **whats to present me from forging a request with a cookie with the same name as the server variables**?
  721. I mean, it is already possible to forge anything client-related, for obvious reason... but **forging info that potentially come from the server**? That seems...awkward...
  723. (again, keep in mind this is just my first reaction, maybe if I think it through I'll realize what I just said is totally stupid :) )
  724. &lt;/blockquote&gt;
  726. &lt;p&gt;Like Francois said, cookies are easily forged client-side anyway, but most developers tend to rely on the &lt;a href=""&gt;truthiness&lt;/a&gt; of our server variables, specifically those that don&amp;#39;t come over in the HTTP request. Let me demonstrate how the issue plays out.&lt;/p&gt;
  728. &lt;p&gt;For our example I have created a method on the HomeController named Test that takes four parameters that match server variable names. Below are the descriptions of each from MSDN&amp;#39;s &lt;a href=""&gt;IIS Server Variables&lt;/a&gt; article:&lt;/p&gt;
  730. &lt;ul&gt;
  731. &lt;li&gt;&lt;strong&gt;REMOTE_ADDR&lt;/strong&gt; MSDN Says, &amp;quot;The IP address of the remote host that is making the request.&amp;quot;&lt;/li&gt;
  732. &lt;li&gt;&lt;strong&gt;LOGON_USER&lt;/strong&gt; MSDN Says, &amp;quot;The Windows account that the user is impersonating while connected to your Web server. Use REMOTE&lt;em&gt;USER, UNMAPPED&lt;/em&gt;REMOTE&lt;em&gt;USER, or AUTH&lt;/em&gt;USER to view the raw user name that is contained in the request header. The only time LOGON_USER holds a different value than these other variables is if you have an authentication filter installed.&amp;quot;&lt;/li&gt;
  733. &lt;li&gt;&lt;strong&gt;REQUEST_METHOD&lt;/strong&gt; MSDN Says, &amp;quot;The method used to make the request. For HTTP, this can be &lt;strong&gt;GET&lt;/strong&gt;, &lt;strong&gt;HEAD&lt;/strong&gt;, &lt;strong&gt;POST&lt;/strong&gt;, and so on.&amp;quot;&lt;/li&gt;
  734. &lt;li&gt;&lt;strong&gt;SERVER_NAME&lt;/strong&gt; The server&amp;#39;s host name, DNS alias, or IP address as it would appear in self-referencing URLs.&lt;/li&gt;
  735. &lt;/ul&gt;
  737. &lt;p&gt;My biggest concern is &lt;strong&gt;LOGON_USER&lt;/strong&gt;. As described by MSDN this variable normally stores whatever the value of REMOTE&lt;em&gt;USER, UNMAPPED&lt;/em&gt;REMOTE&lt;em&gt;USER, or AUTH&lt;/em&gt;USER is, except when you have a third party authentication filter installed. The purpose of these authentication filters is to map the value of one of the above three request variables to a different local name. For example, you may be using a filter to map &amp;quot;DOMAINTroyGoode&amp;quot; to &amp;quot;DOMAIN-DMZStandardUser&amp;quot; and to map &amp;quot;DOMAINScottGuthrie&amp;quot; to &amp;quot;DOMAIN-DMZAdministrator&amp;quot;. If you are using such a filter and then add LOGON_USER as a parameter to one of your actions, you are suddenly opening up the ability for anyone to circumvent that authentication filter.&lt;/p&gt;
  739. &lt;p&gt;Here is the action I have created:&lt;/p&gt;
  741. &lt;script src=""&gt; &lt;/script&gt;
  743. &lt;p&gt;And here is what this action will output without any fiddling:&lt;/p&gt;
  745. &lt;p&gt;&lt;img src="/custom/files/old/Unhacked_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  747. &lt;p&gt;Now I&amp;#39;ll tweak the Url a bit:&lt;/p&gt;
  749. &lt;blockquote&gt;
  750. First Url:
  752. http://localhost:63260/Home/Test
  754. Second Url:
  756. http://localhost:63260/Home/Test?REMOTE_ADDR=Any.IP.I.Want&amp;LOGON_USER=YourDomainAdministrator&amp;REQUEST_METHOD=POST&amp;
  757. &lt;/blockquote&gt;
  759. &lt;p&gt;And voil&amp;agrave;, mischief achieved:&lt;/p&gt;
  761. &lt;p&gt;&lt;img src="/custom/files/old/TotallyHaxxored_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  763. &lt;p&gt;Now I&amp;#39;m no Kevin Mitnick, but I can assure you that if I can come up with something like this in an hour or so, a dedicated hacker that is probably far smarter than I will likely give you a lot of heartache if you make use of this feature. Have any &amp;quot;developer mode checks&amp;quot; that check for or localhost? Have any filters to try and prevent GETs on certain actions? Relying on server variables passed in to your actions would make those scenarios (and many others) unwise. Just say no.&lt;/p&gt;
  765. &lt;p&gt;In my opinion this feature (the server variable portion) should just be removed from the MVC framework entirely or something should be put in place to prevent overwriting parameters named the same as a server variable. &lt;/p&gt;
  766. &lt;div class="feedflare"&gt;
  767. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  768. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  769. <feedburner:origLink></feedburner:origLink></entry>
  770. <entry>
  771.   <title>MVC Membership - Preview 3</title>
  772.   <link href="" />
  773.   <updated>2008-07-02T00:00:00+00:00</updated>
  774.   <id></id>
  775.   <content type="html">&lt;p&gt;Tonight we posted a &lt;a href=""&gt;new release of the MVC Membership Starter Kit&lt;/a&gt;. This release is an update to migrate the starter kit to &lt;a href=""&gt;the new Preview 3 release of the MVC framework&lt;/a&gt;. While several bugs have been squashed, no major new functionality has been added.&lt;/p&gt;
  777. &lt;p&gt;If you couldn&amp;#39;t wait and downloaded the source prior to the official Preview 3 release, you&amp;#39;ll still want to download tonight&amp;#39;s official release as several important issues have been addressed.&lt;/p&gt;
  779. &lt;h2&gt;Bug Fixes in 1.3:&lt;/h2&gt;
  781. &lt;ul&gt;
  782. &lt;li&gt;The System.Web.Abstraction, System.Web.Mvc, and System.Web.Routing DLLs being used prior to tonight were from an earlier Preview 3 release and were not signed by Microsoft.&lt;/li&gt;
  783. &lt;li&gt;Routing ambiguities caused a 404 error to occur when a user enters an incorrect username/password combination on the login page.&lt;/li&gt;
  784. &lt;li&gt;Several errors were occurring on various password recovery screens which created a bad user experience.&lt;/li&gt;
  785. &lt;li&gt;Errors on the administration section&amp;#39;s Create User and Display User pages were preventing that functionality from working at all.&lt;/li&gt;
  786. &lt;/ul&gt;
  788. &lt;p&gt;Thanks for all of the interest everyone has shown in this project and thanks to &lt;a href=""&gt;Maarten&lt;/a&gt; and &lt;a href=""&gt;Greg&lt;/a&gt; for their contributions; especially to Maarten as he did most of the grunt work in upgrading our code base to Preview 3. Please send any feedback you have our way, we&amp;#39;d love to hear it!&lt;/p&gt;
  789. &lt;div class="feedflare"&gt;
  790. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  791. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  792. <feedburner:origLink></feedburner:origLink></entry>
  793. <entry>
  794.   <title>SSL Links/URLs in MVC</title>
  795.   <link href="" />
  796.   <updated>2008-06-11T00:00:00+00:00</updated>
  797.   <id></id>
  798.   <content type="html">&lt;p&gt;A couple days ago a reader sent me a question regarding how to use SSL with the MVC framework. Specifically the reader wanted to know the easiest way to make an Ajax call to a HTTPS page from a non HTTPS page. The tricky part here is to do so without hard-coding any URLs (as one of the best practices of the MVC framework is that views and controllers should be divorced from the routes that access them).&lt;/p&gt;
  800. &lt;p&gt;Currently an ActionLink like:&lt;/p&gt;
  802. &lt;script src=""&gt; &lt;/script&gt;
  804. &lt;p&gt;... outputs the following hyperlink:&lt;/p&gt;
  806. &lt;script src=""&gt; &lt;/script&gt;
  808. &lt;p&gt;I&amp;#39;ve created a few extension methods that enable you to fully-qualify these URLs and change the protocol to HTTPS at run-time. Using the extension method &amp;quot;ToSslLink&amp;quot; like so:&lt;/p&gt;
  810. &lt;script src=""&gt; &lt;/script&gt;
  812. &lt;p&gt;... now outputs a hyperlink with protocol, server, port, etc:&lt;/p&gt;
  814. &lt;script src=""&gt; &lt;/script&gt;
  816. &lt;p&gt;If you&amp;#39;re using Ajax, however, you&amp;#39;ll be more interested in getting to the URL directly rather than building an entire hyperlink. In that case you can use &amp;quot;ToSslUrl&amp;quot;:&lt;/p&gt;
  818. &lt;script src=""&gt; &lt;/script&gt;
  820. &lt;p&gt;... to output this:&lt;/p&gt;
  822. &lt;script src=""&gt; &lt;/script&gt;
  824. &lt;p&gt;Here is the code for the extension methods I&amp;#39;ve created, hopefully some of you will find this useful:&lt;/p&gt;
  826. &lt;script src=""&gt; &lt;/script&gt;
  828. &lt;p&gt;One important missing element from all is this posting to a form via HTTPS from a non-HTTPS page. You can certainly create your form tags manually and populate the action attribute using Url.Action(...).ToSslUrl(), but you cannot try and combine these extension methods with the Html.Form(...) helper that is most commonly used inside a using statement.&lt;/p&gt;
  830. &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The above code was updated on July 7th, 2008 to fix a bug reported by &lt;a href=""&gt;Mike Hadlow&lt;/a&gt;. Thanks Mike!&lt;/p&gt;
  831. &lt;div class="feedflare"&gt;
  832. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  833. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  834. <feedburner:origLink></feedburner:origLink></entry>
  835. <entry>
  836.   <title>Help Decide Sandcastle's Fate</title>
  837.   <link href="" />
  838.   <updated>2008-06-10T00:00:00+00:00</updated>
  839.   <id></id>
  840.   <content type="html">&lt;p&gt;&lt;a href=""&gt;Sandcastle&lt;/a&gt; - the .Net community equivalent of &lt;a href=""&gt;RDoc&lt;/a&gt;/&lt;a href=""&gt;JavaDoc&lt;/a&gt; and the spiritual successor of the now defunct &lt;a href=""&gt;NDoc&lt;/a&gt; &amp;ndash; &lt;a href=""&gt;has been removed from CodePlex&lt;/a&gt;. It&amp;#39;s fate is currently up in the air and Microsoft is asking you for input on what should happen next. It was pulled down after the community at-large expressed reservations about Sandcastle being hosted on &lt;a href=""&gt;CodePlex&lt;/a&gt; while not being published under an Open Source license or even being posted in source form at all. According to the announcement on MSDN, the possible future for Sandcastle involves two scenarios: &lt;/p&gt;
  842. &lt;ul&gt;
  843. &lt;li&gt;Publish the source code for Sandcastle and revive this project in Codeplex&lt;/li&gt;
  844. &lt;li&gt;Migrate sandcastle to MSDN Code gallery at &lt;a href=""&gt;;/a&gt;&lt;/li&gt;
  845. &lt;/ul&gt;
  847. &lt;p&gt;I for one would love to see Sandcastle released as an open source project on CodePlex. It seems to me that Microsoft has had a great deal of success lately with releasing the MVC Framework as an open source project and I hope that they continue the trend. If you have used Sandcastle or foresee the need to have automatic code documentation generation on a project in the future, please do not hesitate to &lt;a href=""&gt;leave a comment&lt;/a&gt; letting the powers that be know how you feel. &lt;/p&gt;
  848. &lt;div class="feedflare"&gt;
  849. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  850. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  851. <feedburner:origLink></feedburner:origLink></entry>
  852. <entry>
  853.   <title>We're Back</title>
  854.   <link href="" />
  855.   <updated>2008-06-08T00:00:00+00:00</updated>
  856.   <id></id>
  857.   <content type="html">&lt;p&gt;After two weeks in gorgeous St. Lucia on honeymoon at the &lt;a href=""&gt;Sandals Grande St. Lucian&lt;/a&gt;, my new bride and I have returned to DC. Take a look at a few of the pictures we snapped along the way.&lt;/p&gt;
  859. &lt;h2&gt;A Few Pictures&lt;/h2&gt;
  861. &lt;p&gt;&lt;img src="/custom/files/old/HeadedToStLucia_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  863. &lt;p&gt;After a hectic weekend, we got our first chance to relax at National Airport, waiting to depart for Miami and then on to St. Lucia.&lt;/p&gt;
  865. &lt;p&gt;&lt;img src="/custom/files/old/OurHomeInStLucia_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  867. &lt;p&gt;The backyard of our home away from home. To the right you can see our private pool (with the waterfall in the background). Not pictured: our outdoor shower &amp;amp; hot tub, plus a hammock that proved perfect for reading and relaxing. All this and only a stone&amp;#39;s throw from the beach!&lt;/p&gt;
  869. &lt;p&gt;&lt;img src="/custom/files/old/AtDinner_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  871. &lt;p&gt;Our butler scheduled an intimate dinner for the two of us at Gordon&amp;#39;s, a restaurant at the end of a pier only a few minutes walk from home. If you&amp;#39;ve never stayed at an all-inclusive, I highly recommend it. It was nice to eat at fine restaurants every night and just get up and leave without worrying about any bill.&lt;/p&gt;
  873. &lt;p&gt;&lt;img src="/custom/files/old/Hobie_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  875. &lt;p&gt;First order of business the first morning in St. Lucia? Sailing. Lots of sailing. My hopes of sailing every day were not to be (so much else to do!), but I did manage to go out every other day or so.&lt;/p&gt;
  877. &lt;p&gt;&lt;img src="/custom/files/old/SwimUpBar_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  879. &lt;p&gt;We heart swim-up bars.&lt;/p&gt;
  881. &lt;p&gt;&lt;img src="/custom/files/old/ThePitons_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  883. &lt;p&gt;St. Lucia&amp;#39;s most famous landmarks, the Pitons, in the background. Also the namesake of St. Lucia&amp;#39;s most popular beer (which tastes remarkably like Corona).&lt;/p&gt;
  885. &lt;p&gt;&lt;img src="/custom/files/old/ForestBridge_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  887. &lt;p&gt;A tour guide led us into the outer fringes of the rainforest, where we wanted to swim in a waterfall.&lt;/p&gt;
  889. &lt;p&gt;&lt;img src="/custom/files/old/Waterfall_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  891. &lt;p&gt;Which we did.&lt;/p&gt;
  893. &lt;p&gt;&lt;img src="/custom/files/old/BackOfBoat_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  895. &lt;p&gt;There was a lot of boating in St. Lucia. This was taken on a wild, wet ride back from the Pitons.&lt;/p&gt;
  897. &lt;p&gt;&lt;img src="/custom/files/old/PoolRaft_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  899. &lt;p&gt;We spent considerably more time in the humongous beach-side pool than on the beach proper. Lesson learned? The ocean needs more swim-up bars.&lt;/p&gt;
  901. &lt;p&gt;&lt;img src="/custom/files/old/Windsurfing_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  903. &lt;p&gt;Windsurfing is hard. Hard, hard.&lt;/p&gt;
  905. &lt;p&gt;&lt;img src="/custom/files/old/Horseback_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  907. &lt;p&gt;Riding horses bare-back in the surf is fun, but it also gave me a very healthy respect for the invention of saddles.&lt;/p&gt;
  909. &lt;p&gt;&lt;img src="/custom/files/old/FrontOfCatamaran_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  911. &lt;p&gt;Taken on the bow of a 50+ foot catamaran, which I&amp;#39;m trying to figure out how to add to my Amazon wish-list.&lt;/p&gt;
  913. &lt;p&gt;&lt;img src="/custom/files/old/ByTheFountain_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  915. &lt;p&gt;Uh oh, the trip is almost over, hurry up and take some nice photos!&lt;/p&gt;
  917. &lt;p&gt;&lt;img src="/custom/files/old/AgainstATree_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  919. &lt;p&gt;Who are these tan people, and what have they done with the folks from the first picture?&lt;/p&gt;
  921. &lt;p&gt;&lt;img src="/custom/files/old/InTheBungalow_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  923. &lt;p&gt;With picture time over, it&amp;#39;s time to relax in a beach-front bungalow until the sun goes down. Afterward it is off to pack and bid St. Lucia farewell in the morning.&lt;/p&gt;
  925. &lt;p&gt;This is only a small selection of our wonderful two weeks. If anyone else is considering a trip with their significant other to the Caribbean, we cannot recommend St. Lucia highly enough and &lt;a href=""&gt;Sandals Grande St. Lucian&lt;/a&gt; was a wonderful place to stay.&lt;/p&gt;
  926. &lt;div class="feedflare"&gt;
  927. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  928. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  929. <feedburner:origLink></feedburner:origLink></entry>
  930. <entry>
  931.   <title>Honeymoon Bound!</title>
  932.   <link href="" />
  933.   <updated>2008-05-20T00:00:00+00:00</updated>
  934.   <id></id>
  935.   <content type="html">&lt;p&gt;I know, I know... I haven&amp;#39;t been blogging much recently, but don&amp;#39;t think that you&amp;#39;ve gotten rid of me yet. My fianc&amp;egrave; and I have been very busy preparing for our wedding, which after nearly a year of planning is now only days away [obligatory Office paraphrase: Mr. Troy Goode... Has a nice ring to it, don&amp;#39;t you think?]. On Monday Alexandra and I will be leaving for the &lt;a href=""&gt;Sandals Grande St. Lucian&lt;/a&gt; for two weeks of sun, sailing, and relaxing. There are still a couple things in the cooker that I&amp;#39;ll be working on after I get back, so hopefully you&amp;#39;ll be hearing more about that toward the end of June. Wish me luck! &lt;/p&gt;
  937. &lt;h2&gt;Visual Studio / ReSharper Settings&lt;/h2&gt;
  939. &lt;p&gt;I&amp;#39;ve been meaning to post my Visual Studio &amp;amp; ReSharper settings for a while, primarily so I have one central place to download the settings from when I set up a new machine at home or work. Feel free to ignore the files I&amp;#39;ve posted below, or try them out to see my modified dark color scheme! &lt;/p&gt;
  941. &lt;p&gt;&lt;a href="/custom/files/old/VS2008.vssettings"&gt;VS2008.vssettings&lt;/a&gt;
  942. &lt;a href="/custom/files/old/Resharper4Settings.xml"&gt;Resharper4Settings.xml&lt;/a&gt;&lt;/p&gt;
  943. &lt;div class="feedflare"&gt;
  944. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  945. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  946. <feedburner:origLink></feedburner:origLink></entry>
  947. <entry>
  948.   <title>MVC Membership Starter Kit - 1.2</title>
  949.   <link href="" />
  950.   <updated>2008-04-28T00:00:00+00:00</updated>
  951.   <id></id>
  952.   <content type="html">&lt;p&gt;This weekend I posted a &lt;a href=";amp;ReleaseId=12667"&gt;new release of the MVC Membership Starter Kit&lt;/a&gt;. This release is an update to migrate the starter kit to &lt;a href=""&gt;the new interim release of the MVC framework&lt;/a&gt;. If you do not feel comfortable using the interim release, please continue using the 1.1 release and wait for Microsoft to release Preview 3; we will update the Starter Kit soon thereafter.&lt;/p&gt;
  954. &lt;h2&gt;Changes in 1.2:&lt;/h2&gt;
  956. &lt;ul&gt;
  957. &lt;li&gt;WindowsLive is now a supported authentication scenario (&lt;a href=""&gt;read Maarten&amp;#39;s blog post on this&lt;/a&gt;).&lt;/li&gt;
  958. &lt;li&gt;Per &lt;a href=""&gt;Andrew Arnott&amp;#39;s&lt;/a&gt; suggestion, the starter kit now uses the &lt;a href=""&gt;DotNetOpenId&lt;/a&gt; library rather than the code previously used (which was created by Mads Kristensen). This gives us a more robust and secure implementation that will develop and improve independently of this project.&lt;/li&gt;
  959. &lt;li&gt;All actions that previously expected a username in the route now expect the user&amp;#39;s ProviderUserKey (a Guid) instead. This was done because users with OpenID urls as their username could not previously be accessed.&lt;/li&gt;
  960. &lt;li&gt;&amp;quot;Whitelist support&amp;quot; has been added to the OpenID implementation, allowing you to setup regular expressions that dictate which OpenID providers are allowed to be used when logging into your site. By default there is no whitelist, so all providers are allowed.&lt;/li&gt;
  961. &lt;li&gt;The starter kit now offers greater control over which authentication scenarios your site supports and which is the default. Out-of-the-box only FormsAuthentication is enabled and is obviously the default.&lt;/li&gt;
  962. &lt;/ul&gt;
  963. &lt;div class="feedflare"&gt;
  964. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  965. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  966. <feedburner:origLink></feedburner:origLink></entry>
  967. <entry>
  968.   <title>Massive Security Hole</title>
  969.   <link href="" />
  970.   <updated>2008-04-13T00:00:00+00:00</updated>
  971.   <id></id>
  972.   <content type="html">&lt;p&gt;A massive security hole in was just revealed that allows anyone to see your passwords... Danny Douglass just added a post to his blog where he explains the issue and provides a patched BlogEngine.Core assembly to resolve the issue until the next release of BlogEngine is available.&lt;/p&gt;
  974. &lt;p&gt;I would advise anyone running to immediately &lt;a href=""&gt;go to Danny&amp;#39;s blog and download &amp;amp; install the fix&lt;/a&gt;.&lt;/p&gt;
  976. &lt;p&gt;The faster we can get word out about this, the faster we can shut down this particular attack vector, so please try and get the word out to any users you are aware of and please &lt;a href=""&gt;kick Danny&amp;#39;s post at DotNetKicks&lt;/a&gt;.&lt;/p&gt;
  978. &lt;p&gt;Thanks Danny!&lt;/p&gt;
  979. &lt;div class="feedflare"&gt;
  980. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  981. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  982. <feedburner:origLink></feedburner:origLink></entry>
  983. <entry>
  984.   <title>OpenID Check_Authentication In C#</title>
  985.   <link href="" />
  986.   <updated>2008-04-11T00:00:00+00:00</updated>
  987.   <id></id>
  988.   <content type="html">&lt;p&gt;Earlier this year Mads Krisensen (of &lt;a href=""&gt;;/a&gt; fame) posted a &lt;a href=""&gt;lightweight implementation of OpenID&lt;/a&gt; using C#. In the comments on Mads&amp;#39; post, &lt;a href=""&gt;Andrew Arnott&lt;/a&gt; (&lt;a href=""&gt;a developer of the DotNetOpenId library&lt;/a&gt;) mentioned that the example Mads had posted could &amp;quot;be hacked with a single change of a word in the URL.&amp;quot; This is what is technically referred to as a &lt;strong&gt;Very Bad Thing&lt;/strong&gt;. Andrew and another poster named &amp;quot;neil&amp;quot; went on to elaborate that implementing OpenID&amp;#39;s &amp;quot;check&lt;em&gt;authentication&amp;quot; algorithm would close this security hole. Unfortunately as of the writing of this article neither Mads nor any of the commentors have provided an implementation of check&lt;/em&gt;authentication that works with the class Mads posted (bear in mind that Andrew only brought up this issue less than a week ago, so Mads may very well be working on it).&lt;/p&gt;
  990. &lt;p&gt;Fast forward to yesterday when I was researching my options for implementing OpenID for the next release of the &lt;a href=""&gt;ASP.Net MVC Membership Starter Kit&lt;/a&gt;. I liked Mads solution more than the other OpenID libraries that are current available because of its brevity and how easy it is to include it in a project without introducing an extra assembly dependency, so I decided to go ahead and add the check_authentication functionality. A quick read of &lt;a href=""&gt;that portion of the OpenID spec&lt;/a&gt; and a couple hours of coding/testing and I think I&amp;#39;m about finished.&lt;/p&gt;
  992. &lt;p&gt;Here is the method you need to add to Mads&amp;#39; class:&lt;/p&gt;
  994. &lt;script src=""&gt; &lt;/script&gt;
  996. &lt;p&gt;Now you need to make sure that method is called from somewhere. I chose to make the method private and just call it from inside the Authenticate method. Within the Authenticate method replace:&lt;/p&gt;
  998. &lt;script src=""&gt; &lt;/script&gt;
  1000. &lt;p&gt;... with...&lt;/p&gt;
  1002. &lt;script src=""&gt; &lt;/script&gt;
  1004. &lt;p&gt;And that&amp;#39;s it!&lt;/p&gt;
  1006. &lt;p&gt;If anyone with more experience than I in OpenID waters sees a problem with my implementation, let me know and I will try to get it fixed quickly.&lt;/p&gt;
  1008. &lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; I am aware that Mads&amp;#39; implementation and the use of &amp;#39;check_authentication&amp;#39; is considered an overly chatty use of OpenID. It seems to me that the extra complexity required to implement OpenID 2.0 protocol is just not worthwhile for most OpenID consumers. Feel free to let me know why this is a stupid position to take.&lt;/p&gt;
  1009. &lt;div class="feedflare"&gt;
  1010. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1011. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1012. <feedburner:origLink></feedburner:origLink></entry>
  1013. <entry>
  1014.   <title>MVC: New Membership Starter Kit Release</title>
  1015.   <link href="" />
  1016.   <updated>2008-04-11T00:00:00+00:00</updated>
  1017.   <id></id>
  1018.   <content type="html">&lt;h2&gt;The Starter Kit&lt;/h2&gt;
  1020. &lt;p&gt;If you haven&amp;#39;t had a chance to read about the MVC Membership Starter Kit I&amp;#39;ve created, &lt;a href="/2008/04/02/mvc-membership-starter-kit/"&gt;read this post first&lt;/a&gt;.&lt;/p&gt;
  1022. &lt;h2&gt;New Release&lt;/h2&gt;
  1024. &lt;p&gt;Since we first created the starter kit a week and a half ago, &lt;a href=""&gt;Maarten Balliauw&lt;/a&gt; and I have been hard at work fleshing out the implementation to provide as much functionality as possible. Last night we finished the last stretch of things we had identified for this release and have posted the code as a new release on CodePlex. Keep in mind you can also always download our latest builds from CodePlex as well without waiting for a new release.&lt;/p&gt;
  1026. &lt;h2&gt;New Features&lt;/h2&gt;
  1028. &lt;h3&gt;OpenID&lt;/h3&gt;
  1030. &lt;p&gt;Mads Kristensen &lt;a href=""&gt;released a lightweight OpenID consumer&lt;/a&gt; earlier this year that I then proceeded to flesh out with &lt;a href="/2008/04/11/openid-check_authentication/"&gt;a security patch&lt;/a&gt;. The reason I did so was so that I could include OpenID in this release of the Starter Kit.&lt;/p&gt;
  1032. &lt;p&gt;Out of the box you can create a route to the OpenIDLogin action, which displays the following view:&lt;/p&gt;
  1034. &lt;p&gt;&lt;img src="/custom/files/old/OpenID_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1036. &lt;p&gt;Once the user has entered their OpenID url, the starter kit will take care of the rest for you, with one critical exception: you have to map the url to a user in your membership database. To do so, you simple override a virtual method and return a MembershipUser, like so:&lt;/p&gt;
  1038. &lt;script src=""&gt; &lt;/script&gt;
  1040. &lt;p&gt;Note that the above implementation maps the OpenID url to a user&amp;#39;s UserName, which may or may not be what you want for your application. Adjust accordingly.&lt;/p&gt;
  1042. &lt;h3&gt;Password Recovery Tools&lt;/h3&gt;
  1044. &lt;p&gt;Maarten did a great job providing users with a way to manage their passwords. While logged in they can change their password:&lt;/p&gt;
  1046. &lt;p&gt;&lt;img src="/custom/files/old/ChangePassword_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1048. &lt;p&gt;Or if they are having trouble logging in, they can submit their username...&lt;/p&gt;
  1050. &lt;p&gt;&lt;img src="/custom/files/old/ForgotPassword_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1052. &lt;p&gt;...and then answer their password question (if the system is configured to require it)...&lt;/p&gt;
  1054. &lt;p&gt;&lt;img src="/custom/files/old/PasswordQuestion_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1056. &lt;p&gt;...and they will then receive their password via email (or a newly generated password -- depending on system configuration).&lt;/p&gt;
  1058. &lt;h3&gt;Client-Side Validation&lt;/h3&gt;
  1060. &lt;p&gt;All non-administrative forms now include basic client-side validation. The validations even change based upon your Membership settings.&lt;/p&gt;
  1062. &lt;p&gt;For instance, by default the ASP.Net Membership provider requires passwords to contain at least 1 non-alphanumeric character. If a user entered a password of &amp;quot;password&amp;quot; they would see the following alert:&lt;/p&gt;
  1064. &lt;p&gt;&lt;img src="/custom/files/old/ClientSideValidation_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1066. &lt;h3&gt;Components: Login &amp;amp; LoginStatus&lt;/h3&gt;
  1068. &lt;p&gt;Maarten created components that emulate the functionality of the old Login and LoginStatus controls. Now it is easy to have a Login box on every page.&lt;/p&gt;
  1070. &lt;h3&gt;Major Refactoring&lt;/h3&gt;
  1072. &lt;p&gt;Most of the controller and filter code has been broken out into a separate assembly.&lt;/p&gt;
  1074. &lt;p&gt;Your FormsAuthentication and FormsAuthenticationAdministration controllers should now inherit from a base version of each. Maarten has created a boat load of virtual method hooks for each action (OnBeforeBlah, OnAfterBlah, OnErrorBlah) that provides you with easy extensibility points without needing to directly modify the starter kit base code.&lt;/p&gt;
  1076. &lt;p&gt;Hopefully this refactoring will make it easy for you to upgrade to future versions of the starter kit&amp;#39;s code as they become available.&lt;/p&gt;
  1078. &lt;h2&gt;The Future&lt;/h2&gt;
  1080. &lt;p&gt;Currently we&amp;#39;ve cleared our plate and have no more planned features to attend to. Does this mean that we are done? No. This is what you can expect to see us working on next:&lt;/p&gt;
  1082. &lt;ul&gt;
  1083. &lt;li&gt;Preview3 updates, whenever it becomes available.&lt;/li&gt;
  1084. &lt;li&gt;Validations on the administrative side.&lt;/li&gt;
  1085. &lt;li&gt;Bug fixes, of course. :-)&lt;/li&gt;
  1086. &lt;li&gt;If you have suggestions for what you would like to see in the next release, please &lt;a href="mailto:[email protected]"&gt;drop me an email&lt;/a&gt; and let me know!&lt;/li&gt;
  1087. &lt;/ul&gt;
  1089. &lt;p&gt;You can &lt;a href=";amp;ReleaseId=12261"&gt;download the new release&lt;/a&gt; from CodePlex. &lt;/p&gt;
  1090. &lt;div class="feedflare"&gt;
  1091. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1092. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1093. <feedburner:origLink></feedburner:origLink></entry>
  1094. <entry>
  1095.   <title>Rob Conery's PagedList Class (Updated)</title>
  1096.   <link href="" />
  1097.   <updated>2008-04-08T00:00:00+00:00</updated>
  1098.   <id></id>
  1099.   <content type="html">&lt;p class="warning"&gt;A new, improved version of this class is now available &lt;a href="/2011/06/28/pagedlist-can-haz-htmlhelperz/"&gt;here&lt;/a&gt;.&lt;/p&gt;
  1101. &lt;p&gt;Robert Muehsig has posted a great user control for the MVC framework that &lt;a href=""&gt;adds pagination links to the bottom of a paged list&lt;/a&gt;. In it he used a slightly customized version of &lt;a href=""&gt;Rob Conery&amp;#39;s PagedList&lt;/a&gt; class that Rob was kind enough to post way back when the first CTP was released. This reminded me that I should probably post the version I have customized, as I think it makes it a bit easier to use and maintain. Check out the code &lt;a href=""&gt;on GitHub.&lt;/a&gt;&lt;/p&gt;
  1103. &lt;h2&gt;Changes from Rob&amp;#39;s version:&lt;/h2&gt;
  1105. &lt;ul&gt;
  1106. &lt;li&gt;&lt;strong&gt;Added a &amp;quot;TotalPages&amp;quot; property.&lt;/strong&gt; If you&amp;#39;re going to loop through each of the pages to display page navigation, you&amp;#39;ll obviously need this.&lt;/li&gt;
  1107. &lt;li&gt;&lt;strong&gt;Changed &amp;quot;IsPreviousPage&amp;quot; to &amp;quot;HasPreviousPage&amp;quot;.&lt;/strong&gt; It just sounds better.&lt;/li&gt;
  1108. &lt;li&gt;&lt;strong&gt;Changed &amp;quot;IsNextPage&amp;quot; to &amp;quot;HasNextPage&amp;quot;.&lt;/strong&gt; See above.&lt;/li&gt;
  1109. &lt;li&gt;&lt;strong&gt;Added a &amp;quot;IsFirstPage&amp;quot; property.&lt;/strong&gt; The opposite way of using the above two properties. I prefer this way, but kept the original way for backwards compatibility (except the naming).&lt;/li&gt;
  1110. &lt;li&gt;&lt;strong&gt;Added a &amp;quot;IsLastPage&amp;quot; property.&lt;/strong&gt; See above.&lt;/li&gt;
  1111. &lt;li&gt;&lt;strong&gt;Changed the first constructor to accept IEnumerable&amp;lt;T&amp;gt; rather than IQueryable&amp;lt;T&amp;gt;.&lt;/strong&gt; I&amp;#39;m not exactly sure why Rob originally made it IQueryable. I&amp;#39;m aware that by passing an IQueryable (LINQ) object to this constructor you&amp;#39;ll avoid retrieving the entire set (only taking the results needed), but since IQueryable inherits from IEnumerable everything should be hunky-dory. He probably had a reason and I&amp;#39;m going to wind up breaking all of my stuff, but IEnumerable is just so much handier. =)&lt;/li&gt;
  1112. &lt;li&gt;&lt;strong&gt;Removed the second constructor.&lt;/strong&gt; The second constructor took List&amp;lt;T&amp;gt;, which is unnecessary after changing the first constructor to accept IEnumerable.&lt;/li&gt;
  1113. &lt;li&gt;&lt;strong&gt;Cleaned up property declarations a bit.&lt;/strong&gt; Mainly to make the page a bit shorter, but also to prevent the multiple calculations that could happen in the original. Also the original allowed the changing of certain properties after an instance was created, which would put the instance into an inconsistent state.&lt;/li&gt;
  1114. &lt;li&gt;&lt;strong&gt;Added argument checking and handled a few exception scenarios more gracefully.&lt;/strong&gt; Trying to make debugging a bit friendlier. &lt;/li&gt;&lt;/li&gt;
  1115. &lt;li&gt;&lt;strong&gt;Removed the second extension method that didn&amp;#39;t specify a pageSize.&lt;/strong&gt; I don&amp;#39;t really think that baking in an extension method that sets pageSize to 10 is a good idea, I&amp;#39;d prefer pageSize to be explicitly set elsewhere by the calling code.&lt;/li&gt;
  1116. &lt;li&gt;&lt;strong&gt;Moved the code to the &amp;quot;System.Collections.Generic&amp;quot; namespace.&lt;/strong&gt; I&amp;#39;m sure a lot of you are breaking out in a cold sweat to see me putting something into a System.* namespace, but I kind of feel like this is something that the .Net team just &amp;quot;forgot&amp;quot;. =) Move it wherever makes you comfortable.&lt;/li&gt;
  1117. &lt;/ul&gt;
  1119. &lt;p&gt;Please note that I took many of these ideas from the commentary below Rob&amp;#39;s original post. I&amp;#39;m sure many of you are using something similar, but I thought it would be useful to get something posted online that is a bit more fleshed out than the original example.&lt;/p&gt;
  1121. &lt;p&gt;Thanks for the great work Rob &amp;amp; Robert!&lt;/p&gt;
  1122. &lt;div class="feedflare"&gt;
  1123. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1124. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1125. <feedburner:origLink></feedburner:origLink></entry>
  1126. <entry>
  1127.   <title>Review: Training With Stephen Walther</title>
  1128.   <link href="" />
  1129.   <updated>2008-04-04T00:00:00+00:00</updated>
  1130.   <id></id>
  1131.   <content type="html">&lt;p&gt;I just finished a four day course on AJAX, LINQ, &amp;amp; MVC taught by &lt;a href=""&gt;Stephen Walther&lt;/a&gt; and wanted to let all of you know that if you are interested in training on any of these topics, I HIGHLY recommend Stephen.&lt;/p&gt;
  1133. &lt;p&gt;You can learn more about the training options he offers by visiting his training website:
  1134. &lt;a href=""&gt;;/a&gt;&lt;/p&gt;
  1136. &lt;p&gt;He also keeps a blog filled with incredibly information -- and long ;-) -- posts on various aspects of ASP.Net at:
  1137. &lt;a href=""&gt;;/a&gt;&lt;/p&gt;
  1139. &lt;p&gt;Read on for more details about my experiences this week.&lt;/p&gt;
  1141. &lt;h2&gt;The Instructor&lt;/h2&gt;
  1143. &lt;p&gt;Stephen is a successful author, having literally &amp;quot;written the book&amp;quot; on ASP.Net (and even ASP Classic!). His book &amp;quot;ASP.NET 3.5 Unleashed&amp;quot; has received excellent reviews from Amazon and I look forward to reading it soon.&lt;/p&gt;
  1145. &lt;p&gt;You can buy Stephen&amp;#39;s book from Amazon here:&lt;/p&gt;
  1147. &lt;p&gt;&lt;a href=""&gt;&lt;img src="/custom/files/old/AspNet35UnleashedCover.jpeg" alt="IMAGE"&gt;&lt;/a&gt;&lt;/p&gt;
  1149. &lt;p&gt;We all found Stephen to be very personable and he obviously has an excellent command on the language and tools available in the .Net ecosystem. Also, anyone that can put up with my constant interruptions and derails for four days in a windowless classroom is clearly a pro. =)&lt;/p&gt;
  1151. &lt;h2&gt;The Course&lt;/h2&gt;
  1153. &lt;p&gt;&lt;a href=""&gt;Danny Douglass&lt;/a&gt; originally contacted Stephen to request that he teach a class for seven of our developers at &lt;a href=""&gt;the organization we work for&lt;/a&gt;. Stephen was kind enough to then customize a course around the technologies we had requested, and that is how we ended up with a one day primer on LINQ &amp;amp; MVC followed by an in-depth training session on AJAX technologies and Microsoft&amp;#39;s ASP.Net AJAX implementation specifically.&lt;/p&gt;
  1155. &lt;p&gt;As anyone that reads my blog regularly knows, I am heavily invested in learning the MVC framework and was highly impressed by Stephens grasp on such a new technology. We may very well have been the first ASP.Net MVC class that anyone has taught anywhere and Stephen managed to teach it quickly and confidently. I was also impressed that he was teaching us things based upon the Preview 2 release of the MVC framework which has only been available publicly for 3 weeks rather than the older December CTP release.&lt;/p&gt;
  1157. &lt;p&gt;As someone that considers himself a strong JavaScript developer, I came into the class a little worried that the JavaScript explanation portions of the program would be more remedial than I wanted. I was wrong. Stephen led a thorough review over the advanced JavaScript features developers need to know to develop world-class AJAX libraries and did so while keeping the pace brisk and managing not to leave anyone in the room behind.&lt;/p&gt;
  1159. &lt;p&gt;As I said above, I recommend Stephen&amp;#39;s training courses to anyone organization interested in learning AJAX, JavaScript, MVC, LINQ, or ASP.Net in general. Thanks for the excellent class Stephen!&lt;/p&gt;
  1161. &lt;p&gt;&lt;strong&gt;Disclaimer: I was not paid or compensated in any way for this endorsement.&lt;/strong&gt;&lt;/p&gt;
  1162. &lt;div class="feedflare"&gt;
  1163. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1164. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1165. <feedburner:origLink></feedburner:origLink></entry>
  1166. <entry>
  1167.   <title>MVC: Membership Starter Kit</title>
  1168.   <link href="" />
  1169.   <updated>2008-04-02T00:00:00+00:00</updated>
  1170.   <id></id>
  1171.   <content type="html">&lt;p class="warning"&gt;A newer version of the Membership Starter Kit is now available. &lt;a href="/2008/04/11/mvc-membership-starter-kit-11/"&gt;Click here&lt;/a&gt; to see what has changed.&lt;/p&gt;
  1173. &lt;h2&gt;Introduction&lt;/h2&gt;
  1175. &lt;p&gt;One of my very first blog posts (and most definitely my most popular so far) revolved around &lt;a href="/2007/12/10/aspnet-mvc-membership-basics/"&gt;how to integrate ASP.Net membership and forms authentication into the ASP.Net MVC framework&lt;/a&gt; which had just been released in it&amp;#39;s December CTP flavor. It has remained popular to this day, but unfortunately the Preview 2 release of the MVC framework has caused much of the code I released in that article to no longer function correctly.&lt;/p&gt;
  1177. &lt;p&gt;Even before the release of Preview 2, I had been planning to extend the samples I was providing to offer more useful features. I don&amp;#39;t know about you, but nearly every website I ever create with ASP.Net requires some kind of security/membership system. My preference is to use the built-in system when possible (except for the horrible Profiles sub-system). This means creating login, logout, &amp;amp; registration functionality every time, as well as creating administrative screens for managing the users that enter your system.&lt;/p&gt;
  1179. &lt;p&gt;WebForms provides some controls to help with the login and registration process, but user administration has always been delegated to either (a) the built-in tool that runs separately and doesn&amp;#39;t work remotely or (b) rolling your own solution. The development of the MVC framework seems to me like a good time to resolve this scenario and provide the community with an array of pre-built tools to help boot-strap projects so that we can stop working on infrastructure and start working on the heart of the individual application.&lt;/p&gt;
  1181. &lt;p&gt;&lt;strong&gt;With that in mind I have created a CodePlex project: the &lt;a href=""&gt;ASP.Net MVC Membership Starter Kit&lt;/a&gt;.&lt;/strong&gt; It currently provides controllers and views for all of the common authentication and user administration needs, including:&lt;/p&gt;
  1183. &lt;ul&gt;
  1184. &lt;li&gt;Login/Logout&lt;/li&gt;
  1185. &lt;li&gt;Registration&lt;/li&gt;
  1186. &lt;li&gt;List of Registered Users&lt;/li&gt;
  1187. &lt;li&gt;User Details / Administration&lt;/li&gt;
  1188. &lt;li&gt;Role Management&lt;/li&gt;
  1189. &lt;/ul&gt;
  1191. &lt;p&gt;A big thanks goes out to Rob Conery, as I borrowed his recent &lt;a href=""&gt;Authentication Filters&lt;/a&gt; and included those, along with my recently released &lt;a href="/2008/04/02/mvc-error-handler-filter/"&gt;Error Handling Filters&lt;/a&gt;.&lt;/p&gt;
  1193. &lt;p&gt;Okay, enough wall o&amp;#39;text. Let&amp;#39;s take a look at some screenshots:&lt;/p&gt;
  1195. &lt;h2&gt;Screenshot Tour&lt;/h2&gt;
  1197. &lt;p&gt;Here is the menu when you first log in:&lt;/p&gt;
  1199. &lt;p&gt;&lt;img src="/custom/files/old/Menu-LoggedOut_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1201. &lt;p&gt;The registration page:&lt;/p&gt;
  1203. &lt;p&gt;&lt;img src="/custom/files/old/Registration_4.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1205. &lt;p&gt;The login page (note that the Administrator&amp;#39;s credentials are displayed to make it easy to get started, you&amp;#39;ll obviously want to change them and remove that note):&lt;/p&gt;
  1207. &lt;p&gt;&lt;img src="/custom/files/old/Login_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1209. &lt;p&gt;Having logged in, here is what the menu looks like now:&lt;/p&gt;
  1211. &lt;p&gt;&lt;img src="/custom/files/old/Menu-LoggedIn_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1213. &lt;p&gt;The current options upon clicking the Security tab:&lt;/p&gt;
  1215. &lt;p&gt;&lt;img src="/custom/files/old/Security_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1217. &lt;p&gt;Clicking &amp;quot;Manage Users&amp;quot; brings you to a list of all users currently registered:&lt;/p&gt;
  1219. &lt;p&gt;&lt;img src="/custom/files/old/ManageUsers_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1221. &lt;p&gt;Clicking on the user takes you to a form that allows you to view their details and edit a few aspects of their profile...&lt;/p&gt;
  1223. &lt;p&gt;&lt;img src="/custom/files/old/User-Top_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1225. &lt;p&gt;as well as view/change the roles they are in and help with password issues:&lt;/p&gt;
  1227. &lt;p&gt;&lt;img src="/custom/files/old/User-Bottom_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1229. &lt;p&gt;From the Security tab you can also go to a list of all the system&amp;#39;s roles, from which you can add/delete roles as you need:&lt;/p&gt;
  1231. &lt;p&gt;&lt;img src="/custom/files/old/Roles_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1233. &lt;p&gt;Clicking on a role from the roles list or the user profile allows you to view/modify the users in that role:&lt;/p&gt;
  1235. &lt;p&gt;&lt;img src="/custom/files/old/UsersInRole_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1237. &lt;p&gt;And finally, the Security tab offers a link to another registration form, geared toward Administrators:&lt;/p&gt;
  1239. &lt;p&gt;&lt;img src="/custom/files/old/CreateUser_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1241. &lt;h2&gt;NSFAQ (Not-So Frequently Asked Questions)&lt;/h2&gt;
  1243. &lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Does this compete with MvcContrib?&lt;br&gt;
  1244. &lt;strong&gt;A:&lt;/strong&gt; No. &lt;a href=""&gt;MvcContrib&lt;/a&gt; is a great project that aims to features like alternate routing and view engines, and IoC integration. This project is simply a starter kit to help get membership-based applications off the ground a little quicker. There is no reason you could not use both projects together.&lt;/p&gt;
  1246. &lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; What dependencies does using this starter kit saddle me with?&lt;br&gt;
  1247. &lt;strong&gt;A:&lt;/strong&gt; Ideally, none, other than the ASP.Net Membership API. Every measure will be taken to avoid using third party libraries, be it JavaScript or .Net. We will strive to separate the code and rely on default settings as much as possible to make it easy for you to customize your installation without anything in the starter kit getting in the way.&lt;/p&gt;
  1249. &lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Who is responsible for this?&lt;br&gt;
  1250. &lt;strong&gt;A:&lt;/strong&gt; Currently, only &lt;a href=""&gt;me&lt;/a&gt;, but I&amp;#39;d like that to change! I&amp;#39;m keenly interested in finding a few other developers that would like to contribute to enhancing the starter kit. Please &lt;a href="mailto:[email protected]"&gt;email me&lt;/a&gt; if you&amp;#39;d like to help!&lt;/p&gt;
  1252. &lt;h2&gt;What&amp;#39;s Next?&lt;/h2&gt;
  1254. &lt;p&gt;There are a few features missing that I would like to include in the very short term. Primarily these are features for end-users, like Change Password and Forgot My Password (both of which are currently available on the administration side). Beyond that, visual cleanup of the forms (and separation of the style sheets) as well as a bit of AJAX-ification of the forms would be nice. If you use the starter kit and have suggestions or criticisms, please post to the &lt;a href=""&gt;Discussions forum&lt;/a&gt; or &lt;a href=""&gt;Issue Tracker&lt;/a&gt;!&lt;/p&gt;
  1256. &lt;p&gt;You can download the latest release from &lt;a href=""&gt;the CodePlex project&lt;/a&gt;. I hope you all find it useful!&lt;/p&gt;
  1257. &lt;div class="feedflare"&gt;
  1258. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1259. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1260. <feedburner:origLink></feedburner:origLink></entry>
  1261. <entry>
  1262.   <title>MVC: Action Filter for Handling Errors</title>
  1263.   <link href="" />
  1264.   <updated>2008-04-02T00:00:00+00:00</updated>
  1265.   <id></id>
  1266.   <content type="html">&lt;p&gt;A few months ago I posted &lt;a href="/2008/01/04/mvc-authentication-and-errors/"&gt;an article and some code&lt;/a&gt; that contained filters for forms authentication and error handling for the Preview 1 (CTP) release of the MVC framework. Unfortunately &lt;a href=""&gt;the Preview 2 release&lt;/a&gt; that was made available a few weeks ago changed enough that the code I posted no longer works. &lt;/p&gt;
  1268. &lt;p&gt;What the Preview 2 release did provide, however, was a new built-in filter framework. Rob Conery has already gone through the trouble of &lt;a href=""&gt;creating authentication filters&lt;/a&gt; that cover most of the functionality I had before, but I have yet to see an implementation of a filter for error handling that I like. I&amp;#39;ve gone ahead and started from scratch, throwing away my old filters, and created a new filter that I think covers most of the same scenarios as my old ErrorHandler filters while being much simpler to implement and use. Hopefully you&amp;#39;ll find it useful. &lt;/p&gt;
  1270. &lt;p&gt;First let&amp;#39;s take a look at a simple use case scenario: &lt;/p&gt;
  1272. &lt;script src=""&gt; &lt;/script&gt;
  1274. &lt;p&gt;In the code above, we have a simple action that displays a product based upon the ID specified. What do we do when no ID is specified though? The &amp;quot;correct&amp;quot; thing to do seems to be to throw an exception, as we&amp;#39;ve done, but now the user will see either (a) an ugly 500 error screen [worst case] or (b) be redirected to the generic error page [best case]. Sometimes we&amp;#39;d like a bit more control than that though... &lt;/p&gt;
  1276. &lt;p&gt;Let&amp;#39;s go ahead and add our error handling filter to this action and tell it that whenever &lt;strong&gt;ArgumentNullException&lt;/strong&gt; is thrown, redirect to the &amp;quot;Products&amp;quot; page, where the user can select a product with a valid ID. &lt;/p&gt;
  1278. &lt;script src=""&gt; &lt;/script&gt;
  1280. &lt;p&gt;So we&amp;#39;ve added a [&lt;strong&gt;RedirectToUrlOnError&lt;/strong&gt;] attribute and supplied it with a &lt;strong&gt;Type&lt;/strong&gt; property - detailing the exception to catch - and a &lt;strong&gt;Url&lt;/strong&gt; property - specifying the &lt;strong&gt;Url&lt;/strong&gt; to navigate to upon a matched exception. You&amp;#39;ll notice we are making a call to the &lt;strong&gt;GetProduct&lt;/strong&gt;(&lt;em&gt;int&lt;/em&gt;) method to retrieve the product&amp;#39;s model so that we can pass it into the view&amp;#39;s ViewData. What if this method were to fail? What if we weren&amp;#39;t entirely certain what exception it would throw, or maybe we didn&amp;#39;t care, we just want to handle any exception except for &lt;strong&gt;ArgumentNullException&lt;/strong&gt; (which is already being handled). In this case we&amp;#39;ll add another filter, but this time we will not specify the &lt;strong&gt;Type&lt;/strong&gt; of exception that it should catch and just tell it that if anything isn&amp;#39;t caught by another error handler redirect to the homepage. &lt;/p&gt;
  1282. &lt;script src=""&gt; &lt;/script&gt;
  1284. &lt;p&gt;You can have as many error handler filters attached to an action as you need, but only one may have no Type specified. &lt;/p&gt;
  1286. &lt;p&gt;Now let&amp;#39;s take a look at the code for the filter itself:&lt;/p&gt;
  1288. &lt;script src=""&gt; &lt;/script&gt;
  1290. &lt;p&gt;So the [&lt;strong&gt;RedirectToUrlOnError&lt;/strong&gt;] attribute inherits from the [&lt;strong&gt;RedirectOnError&lt;/strong&gt;] attribute, which is where most of the hard work is done. We&amp;#39;ll take a look at that base class in a bit, but first let&amp;#39;s look at the other attribute you can use to trap and respond to errors - the [&lt;strong&gt;RedirectToActionOnError&lt;/strong&gt;] attribute. We&amp;#39;ll continue with the &lt;strong&gt;Product&lt;/strong&gt;(&lt;em&gt;id&lt;/em&gt;) sample from above, but this time redirect to an action rather than a hardcoded Url:&lt;/p&gt;
  1292. &lt;script src=""&gt; &lt;/script&gt;
  1294. &lt;p&gt;You can see that this time instead of providing the Url property we are using providing the type of the controller that contains our target action, and the name of the action as a string. (Unfortunately lambda expressions are not allowed as parameters to an attribute, so I was limited in my options here. If you have a better idea, please let me know!) Also note that the catch-all is still there as a [&lt;strong&gt;RedirectToUrlOnError&lt;/strong&gt;] attribute. You may use the [&lt;strong&gt;RedirectToActionOnError&lt;/strong&gt;] attribute as a catch-all and you can mix and match the two attribute types, but still only one catch-all attribute total is allowed per action (in other words, you cannot have one of each).&lt;/p&gt;
  1296. &lt;p&gt;Now let&amp;#39;s see the code for this filter:&lt;/p&gt;
  1298. &lt;script src=""&gt; &lt;/script&gt;
  1300. &lt;p&gt;Other than some complexity with determining the Url, everything is very similar to the other filter. Again it appears the base class is doing the heavy lifting. Let&amp;#39;s finally take a look at that base class:&lt;/p&gt;
  1302. &lt;script src=""&gt; &lt;/script&gt;
  1304. &lt;p&gt;That&amp;#39;s all there is. Feel free to take it, use it, change it, whatever. I tried my best to document it thoroughly with comments, but if you have any questions just drop a comment below and I&amp;#39;ll try to respond quickly. I do ask that if you make any improvements, please leave a comment here letting everyone know what you&amp;#39;ve changed so that we can all benefit. &lt;/p&gt;
  1306. &lt;h2&gt;Here are the filters in a downloadable format:&lt;/h2&gt;
  1308. &lt;p&gt;&lt;a href="/custom/files/old/"&gt;;/a&gt;&lt;/p&gt;
  1309. &lt;div class="feedflare"&gt;
  1310. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1311. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1312. <feedburner:origLink></feedburner:origLink></entry>
  1313. <entry>
  1314.   <title>MVC: How Do I RedirectToAction While Passing a Parameter?</title>
  1315.   <link href="" />
  1316.   <updated>2008-04-01T00:00:00+00:00</updated>
  1317.   <id></id>
  1318.   <content type="html">&lt;p&gt;A common scenario that seems under-documented to me in the latest MVC release, is how does one use RedirectToAction while passing a value to that action?&lt;/p&gt;
  1320. &lt;p&gt;In the December CTP, you would do this:&lt;/p&gt;
  1322. &lt;script src=""&gt; &lt;/script&gt;
  1324. &lt;p&gt;The new syntax is close, but not easily discoverable. Instead of the above, from now on you should use:&lt;/p&gt;
  1326. &lt;script src=""&gt; &lt;/script&gt;
  1327. &lt;div class="feedflare"&gt;
  1328. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1329. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1330. <feedburner:origLink></feedburner:origLink></entry>
  1331. <entry>
  1332.   <title>MVC: How Do I Prevent Exposing a Public Method on a Controller?</title>
  1333.   <link href="" />
  1334.   <updated>2008-03-31T00:00:00+00:00</updated>
  1335.   <id></id>
  1336.   <content type="html">&lt;p&gt;The purists will say that you shouldn&amp;#39;t have any public methods on a controller that aren&amp;#39;t meant to be exposed via a view or redirect to another action. Assuming that you, like I, have encountered a situation where you need/want to do this, however, here is what you do:&lt;/p&gt;
  1338. &lt;script src=""&gt; &lt;/script&gt;
  1340. &lt;p&gt;The &lt;strong&gt;System.Web.Mvc.NonAction&lt;/strong&gt; attribute will prevent your public method from being accessed via any routes.&lt;/p&gt;
  1341. &lt;div class="feedflare"&gt;
  1342. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1343. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1344. <feedburner:origLink></feedburner:origLink></entry>
  1345. <entry>
  1346.   <title>Lambdas Using Funcs and Actions</title>
  1347.   <link href="" />
  1348.   <updated>2008-02-12T00:00:00+00:00</updated>
  1349.   <id></id>
  1350.   <content type="html">&lt;p&gt;Many of you are probably familiar with &lt;a href=""&gt;lambda expressions&lt;/a&gt; by now, as they have been extensively covered since the release of .Net 3.5. Most articles tend to focus on how to pass a lambda expression into a method, but how do you create a method that accepts a lambda expression? Enter the &lt;strong&gt;&lt;a href=""&gt;Func&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href=""&gt;Action&lt;/a&gt;&lt;/strong&gt; types...&lt;/p&gt;
  1352. &lt;h2&gt;Funcs vs. Actions&lt;/h2&gt;
  1354. &lt;p&gt;&lt;strong&gt;Funcs&lt;/strong&gt; and &lt;strong&gt;Actions&lt;/strong&gt; are extremely similar; both give you first class support for passing an anonymous method into another method. The difference is in the return value: &lt;strong&gt;Funcs&lt;/strong&gt; have one, &lt;strong&gt;Actions&lt;/strong&gt; do not.&lt;/p&gt;
  1356. &lt;h2&gt;A Simple Action Consumer&lt;/h2&gt;
  1358. &lt;p&gt;There are several variants of the &lt;strong&gt;Action&lt;/strong&gt; type, each taking a varying number of generic parameters. The simplest generic &lt;strong&gt;Action&lt;/strong&gt; takes one generic parameters: the type of the object to be passed into the &lt;strong&gt;Action&lt;/strong&gt;.&lt;/p&gt;
  1360. &lt;p&gt;Suppose you had a list of articles and wanted to iterate through them and modify each of them in some way, but only the ones that were created before 2008. In this case you should probably use a &lt;strong&gt;foreach&lt;/strong&gt; loop, but instead I&amp;#39;ll show you how to do it by encapsulating that &lt;strong&gt;foreach&lt;/strong&gt; loop in another method that then calls your lambda:&lt;/p&gt;
  1362. &lt;script src=""&gt; &lt;/script&gt;
  1364. &lt;p&gt;I&amp;#39;ll be the first to admit it isn&amp;#39;t the finest example of coding practices, but I believe it illustrates how you can use an &lt;strong&gt;Action&lt;/strong&gt; to pass processing in as a parameter.&lt;/p&gt;
  1366. &lt;h2&gt;A Simple Func Consumer&lt;/h2&gt;
  1368. &lt;p&gt;What if you want to pass in your processing and retrieve a return value? Use the &lt;strong&gt;Func&lt;/strong&gt; type. Let&amp;#39;s keep the same example as above, but this time we&amp;#39;ll place variable processing in the lambda to manipulate the article&amp;#39;s title differently based upon the year the article was published:&lt;/p&gt;
  1370. &lt;script src=""&gt; &lt;/script&gt;
  1372. &lt;p&gt;In the above example you&amp;#39;ll see that we have changed &lt;strong&gt;Action&lt;/strong&gt; to &lt;strong&gt;Func&lt;/strong&gt; in the &lt;strong&gt;IterateArticles&lt;/strong&gt; method signature and that we have added a string to the list of types in the &lt;strong&gt;Func&lt;/strong&gt; definition. &lt;em&gt;When using a *&lt;/em&gt;Func*&lt;em&gt;, the last generic parameter is always the return type.&lt;/em&gt; You should also note that we can now return a value from our anonymous method.&lt;/p&gt;
  1374. &lt;h2&gt;A Two-Parameter Func&lt;/h2&gt;
  1376. &lt;p&gt;Finally let&amp;#39;s take a look at an example of a multi-parameter &lt;strong&gt;Func&lt;/strong&gt;. Once again we&amp;#39;ll use the same example, except this time rather than passing the &lt;strong&gt;Article&lt;/strong&gt; object to the anonymous method we&amp;#39;ll pass only the data it needs: the date created and the title:&lt;/p&gt;
  1378. &lt;script src=""&gt; &lt;/script&gt;
  1380. &lt;p&gt;Here we have specified three generic parameters for the &lt;strong&gt;Func&lt;/strong&gt;; two to be passed in, one to return. In our lambda expression we have also had to wrap the &amp;quot;x,y&amp;quot; in parentheses to prevent the compiler from throwing an error because it thinks the comma is intended to separate parameters to the &lt;strong&gt;IterateArticles&lt;/strong&gt; method rather than the &lt;strong&gt;Func.&lt;/strong&gt;&lt;/p&gt;
  1382. &lt;h2&gt;A Zero-Parameter Func&lt;/h2&gt;
  1384. &lt;p&gt;Occasionally you may need to use a &lt;strong&gt;Func&lt;/strong&gt; that will not require any parameters. Trying to pass this into the lambda consumer using only the &amp;quot;{...}&amp;quot; notation of anonymous methods will not work, you will need to use &amp;quot;()=&amp;gt;{...}&amp;quot; as seen below:&lt;/p&gt;
  1386. &lt;script src=""&gt; &lt;/script&gt;
  1388. &lt;p&gt;I hope this helps get you started creating your own lambda consuming methods. Keep in mind that &lt;strong&gt;Funcs&lt;/strong&gt; and &lt;strong&gt;Actions&lt;/strong&gt; are not limited to just one or two parameters as shown in this article; both can accept up to four input parameters (not including the &lt;strong&gt;Func&amp;#39;s&lt;/strong&gt; extra return parameter). As you become more comfortable creating lambda expressions and lambda consumers I am certain you will find many places in our your code that can be simplified and/or made more flexible by using them. &lt;/p&gt;
  1389. &lt;div class="feedflare"&gt;
  1390. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1391. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1392. <feedburner:origLink></feedburner:origLink></entry>
  1393. <entry>
  1394.   <title>Storing LINQ Objects in SQL-Based Session State</title>
  1395.   <link href="" />
  1396.   <updated>2008-01-30T00:00:00+00:00</updated>
  1397.   <id></id>
  1398.   <content type="html">&lt;p&gt;Scott Hanselman &lt;a href=""&gt;recently posted about various options you have for session storage&lt;/a&gt; while using ASP.Net. In the comments of his post I brought up an issue I recently encountered at work (where we use SQL Server session state):&lt;/p&gt;
  1400. &lt;p&gt;&lt;strong&gt;LINQ-To-Sql generated objects are not marked [Serializable] and cannot be stored in out-of-process session storage.&lt;/strong&gt;&lt;/p&gt;
  1402. &lt;p&gt;To get around this I have whipped up the following helper class which will serialize LINQ-To-Sql objects if you set the DataContext&amp;#39;s Serializable property to &amp;quot;Unidirectional&amp;quot;.&lt;/p&gt;
  1404. &lt;p&gt;&lt;strong&gt;Note: The following class does not current work for storing List&amp;lt;X&amp;gt; where X is a LINQ-To-Sql object. I&amp;#39;ll be working to resolve that sometime later this week.&lt;/strong&gt;&lt;/p&gt;
  1406. &lt;script src=""&gt; &lt;/script&gt;
  1407. &lt;div class="feedflare"&gt;
  1408. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1409. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1410. <feedburner:origLink></feedburner:origLink></entry>
  1411. <entry>
  1412.   <title>MVC: Strongly Typed ViewData Without A Code-Behind</title>
  1413.   <link href="" />
  1414.   <updated>2008-01-07T00:00:00+00:00</updated>
  1415.   <id></id>
  1416.   <content type="html">&lt;p&gt;If you&amp;#39;ve tried to use strongly-typed &lt;strong&gt;ViewData&lt;/strong&gt; with a &lt;strong&gt;ViewPage&lt;/strong&gt; or &lt;strong&gt;ViewContentPage&lt;/strong&gt; without using a code-behind file you may have run into the curious scenario of how to specify a generic in the &lt;strong&gt;&amp;lt;%@ Page %&amp;gt;&lt;/strong&gt; element&amp;#39;s &lt;strong&gt;Inherits&lt;/strong&gt; attribute.&lt;/p&gt;
  1418. &lt;h2&gt;The Problem&lt;/h2&gt;
  1420. &lt;p&gt;Let&amp;#39;s say you wanted to specify that the &lt;strong&gt;ViewData&lt;/strong&gt; for this view would be an integer. Normally you would specify this in the code-behind like so:&lt;/p&gt;
  1422. &lt;script src=""&gt; &lt;/script&gt;
  1424. &lt;p&gt;Since we don&amp;#39;t have a code-behind file though, we have to change the &lt;em&gt;.aspx&lt;/em&gt; file&amp;#39;s &lt;strong&gt;&amp;lt;%@ Page %&amp;gt;&lt;/strong&gt; element. Trying to set it to the following will not work:&lt;/p&gt;
  1426. &lt;script src=""&gt; &lt;/script&gt;
  1428. &lt;h2&gt;The Basic Answer&lt;/h2&gt;
  1430. &lt;p&gt;The value of the &lt;strong&gt;Inherits&lt;/strong&gt; attribute appears to be delivered straight to the CLR without any language specific parsing, which means we have to specify it the way the CLR wants to interpret it. I browsed around and found (&lt;a href=""&gt;here&lt;/a&gt; and &lt;a href=";amp;wa=wsignin1.0"&gt;here&lt;/a&gt;) some information that points out the proper way to do this:&lt;/p&gt;
  1432. &lt;script src=""&gt; &lt;/script&gt;
  1434. &lt;h2&gt;WTF?&lt;/h2&gt;
  1436. &lt;p&gt;Eww, huh? The syntax is gnarly, but it gets the job done. Let&amp;#39;s break the syntax down to make sure you understand what is going on:&lt;/p&gt;
  1437. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-" data-lang=""&gt;ParentType`1[ [ChildType,ChildTypeAssembly] ]
  1438. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  1439. &lt;ul&gt;
  1440. &lt;li&gt;&lt;em&gt;&amp;quot;ParentType&amp;quot;&lt;/em&gt; is fairly obvious. This is the generic object that you want to create a reference to.&lt;/li&gt;
  1441. &lt;li&gt;&lt;em&gt;&amp;quot;&amp;#x60;1[ [&amp;quot;&lt;/em&gt; is a bit more obscure. The &amp;quot;&amp;#x60;1&amp;quot; specifies the number of generics in this argument, which we&amp;#39;ll come back to in a second. The double square brackets are required. A single square bracket will &lt;strong&gt;NOT&lt;/strong&gt; work.&lt;/li&gt;
  1442. &lt;li&gt;&lt;em&gt;&amp;quot;ChildType&amp;quot;&lt;/em&gt; is the type of object you wish to have the generic consume (what is the proper terminology here? anyone know?).&lt;/li&gt;
  1443. &lt;li&gt;&lt;em&gt;&amp;quot;ChildTypeAssembly&amp;quot;&lt;/em&gt; is the name of the assembly (&lt;strong&gt;NOT&lt;/strong&gt; the namespace) that contains the &lt;em&gt;ChildType&lt;/em&gt;. All of your common value types will be located in &amp;quot;&lt;strong&gt;mscorlib&lt;/strong&gt;&amp;quot;.&lt;/li&gt;
  1444. &lt;/ul&gt;
  1446. &lt;h2&gt;Multiple Generic Types&lt;/h2&gt;
  1448. &lt;p&gt;Let&amp;#39;s say &lt;strong&gt;ViewPage&lt;/strong&gt; took two arguments as part of its generic declaration area (ie: &lt;strong&gt;ViewPage&amp;lt;X,Y&amp;gt;&lt;/strong&gt;). It doesn&amp;#39;t, by the way, but we&amp;#39;ll pretend it does for the sake of argument; you may find this information useful someday.&lt;/p&gt;
  1450. &lt;p&gt;To have two type parameters, you&amp;#39;ll have to change the &amp;quot;&amp;#x60;1&amp;quot; to a &amp;quot;&amp;#x60;2&amp;quot; and add an extra &lt;strong&gt;&amp;quot;[ChildType, ChildTypeAssembly]&amp;quot;&lt;/strong&gt; reference, separated by a space. More parameters would continue to follow the same logic.&lt;/p&gt;
  1452. &lt;p&gt;If you wanted to achieve the equivalent of &lt;strong&gt;ViewPage&amp;lt;int,string&amp;gt;&lt;/strong&gt; it would look like this:&lt;/p&gt;
  1453. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-" data-lang=""&gt;System.Web.Mvc.ViewPage`2[ [System.Int32,mscorlib], [System.String,mscorlib] ]
  1454. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  1455. &lt;h2&gt;A Generic of Generics&lt;/h2&gt;
  1457. &lt;p&gt;A more likely scenario is that you may want to have your &lt;strong&gt;ViewData&lt;/strong&gt; be a generic &lt;strong&gt;List&amp;lt;T&amp;gt;&lt;/strong&gt;. In this case you&amp;#39;ll just nest the declarations. If you wanted to pass &lt;strong&gt;ViewData&lt;/strong&gt; of the type &lt;strong&gt;List&amp;lt;string&amp;gt;&lt;/strong&gt; to the &lt;strong&gt;ViewPage&lt;/strong&gt; it would look like:&lt;/p&gt;
  1458. &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="language-" data-lang=""&gt;System.Web.Mvc.ViewPage`1[[System.Collections.Generic.List`1[[System.String,mscorlib]], mscorlib]]
  1459. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
  1460. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1461. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1462. <feedburner:origLink></feedburner:origLink></entry>
  1463. <entry>
  1464.   <title>BlogEngine Extension: Copy Code to Clipboard</title>
  1465.   <link href="" />
  1466.   <updated>2008-01-07T00:00:00+00:00</updated>
  1467.   <id></id>
  1468.   <content type="html">&lt;p&gt;Since I first started this blog I&amp;#39;ve been using Colin Coller&amp;#39;s &lt;a href=""&gt;CopySourceAsHtml plugin&lt;/a&gt; for Visual Studio (which &lt;a href=""&gt;Guy Burstein updated&lt;/a&gt; for Visual Studio 2008&amp;#39;s RTM). It was a nice little tool but as I started posting more and more code snippets to the blog I found myself wanting some additional features, specifically: &lt;/p&gt;
  1470. &lt;ul&gt;
  1471. &lt;li&gt;&lt;strong&gt;Easy to use&lt;/strong&gt;. While it was perfectly simple to copy the source as html, it was a bit more cumbersome to paste it properly into &lt;a href=""&gt;Windows Live Writer&lt;/a&gt;. I wound up in HTML mode in WLW everytime I needed to paste some code.&lt;/li&gt;
  1472. &lt;li&gt;&lt;strong&gt;CSS support&lt;/strong&gt;. The Html generated by the VS plugin inlines all of the styles and makes it difficult to change the presentation of your code without tweaking the settings of the plugin at posting time.&lt;/li&gt;
  1473. &lt;li&gt;&lt;strong&gt;Scrollable&lt;/strong&gt;. This is mostly handled by the above feature, but I wanted to be able to limit the amount of screen real estate taken up by the code while still allowing my readers to view more of the code without having to download any files.&lt;/li&gt;
  1474. &lt;li&gt;&lt;strong&gt;Copyable&lt;/strong&gt;. Sometimes you see a piece of code that fits your situation perfectly, but when you copy it you wind up with a bunch of extra Html guck and line numbers at the front of every line you have to manually remove. I want to allow my readers to copy the code without any of that mess.&lt;/li&gt;
  1475. &lt;/ul&gt;
  1477. &lt;p&gt;I found &lt;a href=""&gt;syntaxhighlighter&lt;/a&gt; on Google Code pretty quickly and was impressed. I&amp;#39;d seen it around on other people&amp;#39;s blogs and loved the &amp;quot;copy to clipboard&amp;quot; feature, but I really wanted a server-side (or pre-posting) highlighter that would take some of the strain off the browser and wanted something with richer WLW integration. &lt;/p&gt;
  1479. &lt;p&gt;After looking at a few more options I finally found &lt;a href=""&gt;Leo Vildosola&amp;#39;s Code Snippet&lt;/a&gt; plugin, which matched up with all of my requirements except for the lack of a built-in &amp;quot;copy to clipboard&amp;quot; feature. With some help from &lt;a href=""&gt;clipboard copying javascript posted at WebChicanery&lt;/a&gt; I set out to build an extension for &lt;a href=""&gt;;/a&gt; that would automatically tack on the copy feature to any code I posted via the Code Snippet plugin. &lt;/p&gt;
  1481. &lt;p&gt;A few hours later, I present the CopyCodeToClipboard extension for! Below you will find an example of the extension displaying it&amp;#39;s own code (mmm... dogfood) and the css I&amp;#39;ve used to style the code on my site. I&amp;#39;ve tried to make the extension css friendly so you can change it&amp;#39;s presentation a great deal without modifying the code. &lt;/p&gt;
  1483. &lt;p&gt;&lt;a href="/custom/files/old/"&gt;;/a&gt;&lt;/p&gt;
  1485. &lt;p&gt;Contains all of the below files in one convenient package. &lt;/p&gt;
  1487. &lt;p&gt;&lt;hr&gt;&lt;/p&gt;
  1489. &lt;p&gt;&lt;a href="/custom/files/old/CopyCodeToClipboard.cs"&gt;CopyCodeToClipboard.cs&lt;/a&gt;&lt;/p&gt;
  1491. &lt;p&gt;This is the actual extension and should be placed into your root/App_Code/Extensions/ folder.&lt;/p&gt;
  1493. &lt;script src=""&gt; &lt;/script&gt;
  1495. &lt;p&gt;&lt;hr&gt;&lt;/p&gt;
  1497. &lt;p&gt;&lt;a href="/custom/files/old/WLWSyntaxHighlighter.css"&gt;WLWSyntaxHighlighter.css&lt;/a&gt;&lt;/p&gt;
  1499. &lt;p&gt;The Css generated by the Windows Live Writer Code Snippet plugin, modified to fit into my blog&amp;#39;s colors. &lt;/p&gt;
  1501. &lt;script src=""&gt; &lt;/script&gt;
  1503. &lt;p&gt;&lt;hr&gt;&lt;/p&gt;
  1505. &lt;p&gt;&lt;a href="/custom/files/old/CopyCodeToClipboard.css"&gt;CopyCodeToClipboard.css&lt;/a&gt;&lt;/p&gt;
  1507. &lt;p&gt;The Css I use to style the little red tab below each code area. This is what you would change to match your blog. &lt;/p&gt;
  1509. &lt;script src=""&gt; &lt;/script&gt;
  1511. &lt;p&gt;&lt;hr&gt;&lt;/p&gt;
  1513. &lt;p&gt;&lt;a href="/custom/files/old/clipboard.swf"&gt;clipboard.swf&lt;/a&gt;&lt;/p&gt;
  1515. &lt;p&gt;A Macromedia Flash file used to circumvent Firefox &amp;amp; Safari&amp;#39;s nasty habit of blocking javascript from interacting with the clipboard. Created (as best I can tell) by Mark O&amp;#39;Sullivan of &lt;a href=""&gt;;/a&gt;. &lt;/p&gt;
  1517. &lt;p&gt;&lt;hr&gt;&lt;/p&gt;
  1519. &lt;p&gt;&lt;strong&gt;Update (July 11, 2008):&lt;/strong&gt;&lt;/p&gt;
  1521. &lt;p&gt;A release of the Code Snippet plug hasn&amp;#39;t been made since the last changes to its source was checked in (in late 2007), so I went ahead and downloaded &amp;amp; built the source. To install the plug place the two DLLs in the zip file from below into Windows Live Writer&amp;#39;s /Plugins/ directory.&lt;/p&gt;
  1523. &lt;p&gt;&lt;a href="/custom/files/old/"&gt;;/a&gt;&lt;/p&gt;
  1524. &lt;div class="feedflare"&gt;
  1525. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1526. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1527. <feedburner:origLink></feedburner:origLink></entry>
  1528. <entry>
  1529.   <title>MVC Authentication and Errors</title>
  1530.   <link href="" />
  1531.   <updated>2008-01-04T00:00:00+00:00</updated>
  1532.   <id></id>
  1533.   <content type="html">&lt;p class="warning"&gt;This article was written for the December CTP release of the MVC framework. Unfortunately, it does not entirely apply to the Preview 2 release or subsequent releases.&lt;/p&gt;
  1535. &lt;p&gt;I love working with the &lt;a href=""&gt;recent CTP release&lt;/a&gt; of the ASP.Net MVC framework, but it is definitely an early release and is lacking many of the developer friendly features that we have grown to rely upon in WebForms. One such feature is WebForm&amp;#39;s easy to understand authentication model.&lt;/p&gt;
  1537. &lt;p&gt;In the WebForms world URLs can be referenced in a web.config file and then have authentication rules applied to them. A rule that says that you must be logged in to view a secure page may look something like:&lt;/p&gt;
  1539. &lt;script src=""&gt; &lt;/script&gt;
  1541. &lt;p&gt;A rule that says only users in the Administrators group may view it might look like this:&lt;/p&gt;
  1543. &lt;script src=""&gt; &lt;/script&gt;
  1545. &lt;p&gt;It didn&amp;#39;t take long for me to run into the lack of any central authentication scheme in the new MVC framework. I searched around and found some &lt;a href=""&gt;older information from prior to the CTP release posted by Fredrik Normen&lt;/a&gt; that seemed to address my issues, but unfortunately one of the features his solution requires did not make its way into the CTP release: attribute based exception handling.&lt;/p&gt;
  1547. &lt;p&gt;Looking through the code samples on the page you see how he uses the .Net frameworks built in &lt;a href=""&gt;&lt;strong&gt;PrincipalPermission&lt;/strong&gt;&lt;/a&gt; attribute (from &lt;strong&gt;System.Security.Permissions&lt;/strong&gt;) to classify an action as demanding the user be in a specific role. If the user is not in that role the .Net framework will throw a &lt;strong&gt;SecurityException&lt;/strong&gt;. What good does that do? Well take a look at line 3 in the below code:&lt;/p&gt;
  1549. &lt;script src=""&gt; &lt;/script&gt;
  1551. &lt;p&gt;The &lt;strong&gt;ExceptionHandler&lt;/strong&gt; attribute appears to take two values:&lt;/p&gt;
  1553. &lt;ul&gt;
  1554. &lt;li&gt;The view to render in the event of an error.&lt;/li&gt;
  1555. &lt;li&gt;The type of error to match against.&lt;/li&gt;
  1556. &lt;/ul&gt;
  1558. &lt;p&gt;So based upon this code the &lt;strong&gt;PrincipalPermission&lt;/strong&gt; will interrogate the user&amp;#39;s roles when the action is requested and if the user is not in the &amp;quot;Admin&amp;quot; role it will throw a &lt;strong&gt;SecurityException&lt;/strong&gt;. At that point the &lt;strong&gt;ExceptionHandler&lt;/strong&gt; will wake up and say &amp;quot;hey I can handle that&amp;quot; and render the view named &amp;quot;Error&amp;quot;. Neat huh? Too bad &lt;strong&gt;ExceptionHandler&lt;/strong&gt; doesn&amp;#39;t exist...&lt;/p&gt;
  1560. &lt;p&gt;Personally I liked most of the concepts that were introduced in Frederik&amp;#39;s post, so I went ahead and began to implement the &lt;strong&gt;ExceptionHandler&lt;/strong&gt; attribute. Along the way I realized that what was really needed was a way to apply filters to a controller. I&amp;#39;ve seen &lt;a href=""&gt;Ivan Carrero&amp;#39;s controller filter implementation&lt;/a&gt;, but I wanted filters that hooked straight into the MVC Controller&amp;#39;s three major lifecycle events: &lt;strong&gt;OnPreAction&lt;/strong&gt;, &lt;strong&gt;OnPostAction&lt;/strong&gt;, and &lt;strong&gt;OnError&lt;/strong&gt;. By doing so I felt I would minimize the difference between code in a filter and code in a controller. Thus was born the &lt;strong&gt;FilterController&lt;/strong&gt;.&lt;/p&gt;
  1562. &lt;h2&gt;Filter Controller&lt;/h2&gt;
  1564. &lt;p&gt;The &lt;strong&gt;FilterController&lt;/strong&gt; is an abstract class deriving from the &lt;strong&gt;System.Web.Mvc.Controller&lt;/strong&gt;. It&amp;#39;s primary purpose is to interrogate itself via reflection when it is created and to then load any attributes that implement the &lt;strong&gt;IControllerFilter&lt;/strong&gt; interface:&lt;/p&gt;
  1566. &lt;script src=""&gt; &lt;/script&gt;
  1568. &lt;p&gt;The filters are then called for each of the three integration events: &lt;strong&gt;OnPreAction&lt;/strong&gt;, &lt;strong&gt;OnPostAction&lt;/strong&gt;, and &lt;strong&gt;OnError&lt;/strong&gt;. Here is what the &lt;strong&gt;OnError&lt;/strong&gt; event does:&lt;/p&gt;
  1570. &lt;script src=""&gt; &lt;/script&gt;
  1572. &lt;p&gt;The &lt;strong&gt;OnPreAction&lt;/strong&gt; and &lt;strong&gt;OnPostAction&lt;/strong&gt; events look almost exactly like the &lt;strong&gt;OnError&lt;/strong&gt; event.&lt;/p&gt;
  1574. &lt;p&gt;To fulfill my initial goal of obtaining functionality similar to that described in Frederik&amp;#39;s post, I have created two filters:&lt;/p&gt;
  1576. &lt;ul&gt;
  1577. &lt;li&gt;&lt;strong&gt;SecurityFilter&lt;/strong&gt;&lt;/li&gt;
  1578. &lt;li&gt;&lt;strong&gt;ErrorHandlerFilter&lt;/strong&gt;&lt;/li&gt;
  1579. &lt;/ul&gt;
  1581. &lt;h2&gt;Security Filter&lt;/h2&gt;
  1583. &lt;p&gt;While the &lt;strong&gt;PrincipalPermission&lt;/strong&gt; attribute used in Frederik&amp;#39;s post handles many security scenarios well, it wasn&amp;#39;t as flexible or keyboard friendly as I would prefer. I created the &lt;strong&gt;SecurityFilter&lt;/strong&gt; and an arrangement of sub-filters to create what I think is an easier solution.&lt;/p&gt;
  1585. &lt;p&gt;To use the security filter in your controller you must first inherit from &lt;strong&gt;FilterController&lt;/strong&gt; and apply the &lt;strong&gt;[SecurityFilter]&lt;/strong&gt; attribute.&lt;/p&gt;
  1587. &lt;script src=""&gt; &lt;/script&gt;
  1589. &lt;p&gt;This alone does nothing, but you are now able to add one or more of the &lt;strong&gt;SecurityFilter&lt;/strong&gt;&amp;#39;s sub-filters to this controller or it&amp;#39;s actions. The sub-filters I have created are:&lt;/p&gt;
  1591. &lt;ul&gt;
  1592. &lt;li&gt;&lt;strong&gt;RequireLogin&lt;/strong&gt; Validates that the user is logged in.&lt;/li&gt;
  1593. &lt;li&gt;&lt;strong&gt;RequireAnonymous&lt;/strong&gt; Validates that the user is NOT logged in.&lt;/li&gt;
  1594. &lt;li&gt;&lt;strong&gt;RequireRole&lt;/strong&gt; Validates that the user is in the specified role.&lt;/li&gt;
  1595. &lt;li&gt;&lt;strong&gt;RequireAnyRole&lt;/strong&gt; Validates that the user is in at least one of the specified roles.&lt;/li&gt;
  1596. &lt;li&gt;&lt;strong&gt;RequireEachRole&lt;/strong&gt; Validates that the user is in every one of the specified roles.&lt;/li&gt;
  1597. &lt;/ul&gt;
  1599. &lt;p&gt;Let&amp;#39;s imagine a controller for a simple bulletin board system. In order to post to this forum you must be logged in, if you want to delete a post you must be in either the &amp;quot;Administrators&amp;quot; role or the &amp;quot;Moderators&amp;quot; role, and if you want to undelete a post you must be in the &amp;quot;Administrators&amp;quot; group. That controller would look something like:&lt;/p&gt;
  1601. &lt;script src=""&gt; &lt;/script&gt;
  1603. &lt;p&gt;By applying the [&lt;strong&gt;RequireLogin&lt;/strong&gt;] attribute to the class you have applied that filter to all of the actions as well, which means you must be logged in to call the &lt;strong&gt;Post&lt;/strong&gt; method. The other two methods use the appropriate version of the role requirement filters to achieve their goal.&lt;/p&gt;
  1605. &lt;p&gt;What happens if the filter validations fail? In the case of an anonymous user attempting to access a restricted resource an &lt;strong&gt;AnonymousAccessException&lt;/strong&gt; (which derives from &lt;strong&gt;SecurityException&lt;/strong&gt;) is thrown while all other scenarios throw a &lt;strong&gt;SecurityException&lt;/strong&gt;. What you do with those exceptions leads us to...&lt;/p&gt;
  1607. &lt;h2&gt;Error Handler Filter&lt;/h2&gt;
  1609. &lt;p&gt;Using the above &lt;strong&gt;ForumController&lt;/strong&gt;, let&amp;#39;s add the &lt;strong&gt;ErrorHandler&lt;/strong&gt; filter:&lt;/p&gt;
  1611. &lt;script src=""&gt; &lt;/script&gt;
  1613. &lt;p&gt;Like with the last filter, this filter by itself does nothing but allow us to use the &lt;strong&gt;ErrorHandler&lt;/strong&gt; sub-filter. Let&amp;#39;s go ahead and add two sub-filters: one to handle security exceptions and one to handle all other exceptions.&lt;/p&gt;
  1615. &lt;p&gt;In the event of a security exception we&amp;#39;ll render the &amp;quot;AccessDenied&amp;quot; view while all other exceptions will render the &amp;quot;SystemError&amp;quot; view:&lt;/p&gt;
  1617. &lt;script src=""&gt; &lt;/script&gt;
  1619. &lt;p&gt;First notice that we are now providing the &lt;strong&gt;ErrorHandlerFilter&lt;/strong&gt; attribute with an option that says &lt;strong&gt;ErrorHandlerMode.Render&lt;/strong&gt;. This is because in the event of an error we want the controller to render the view with the name passed in. Later on we&amp;#39;ll look at the other mode: &lt;strong&gt;ErrorHandlerMode.Redirect&lt;/strong&gt;.&lt;/p&gt;
  1621. &lt;p&gt;Next notice that we are providing three values to each of the two &lt;strong&gt;ErrorHandler&lt;/strong&gt; sub-filters:&lt;/p&gt;
  1623. &lt;ul&gt;
  1624. &lt;li&gt;The order in which the sub-filter should be processed. This is important because the order the attribute is returned by reflection is unknown.&lt;/li&gt;
  1625. &lt;li&gt;The name of the view to render. Just like calling &lt;strong&gt;RenderView&lt;/strong&gt;() from an action, this view name must be accessible to the controller (either in the controller&amp;#39;s view directory or in the &lt;strong&gt;Shared&lt;/strong&gt; directory).&lt;/li&gt;
  1626. &lt;li&gt;The type of the exception to match against.&lt;/li&gt;
  1627. &lt;/ul&gt;
  1629. &lt;p&gt;Keep in mind that these sub-filters could be applied at either the class level or the method level and that method-level sub-filters are processed before class-level sub-filters. We&amp;#39;ll stick with class-level throughout this article.&lt;/p&gt;
  1631. &lt;p&gt;An &amp;quot;Access Denied&amp;quot; page popping up whenever we try to go somewhere we aren&amp;#39;t allowed to without logging in isn&amp;#39;t the best user experience. Let&amp;#39;s improve it by sending anonymous users to the login page instead. This time however, we don&amp;#39;t want just render the login view, we want to actually redirect to the &lt;strong&gt;SecurityController&lt;/strong&gt;&amp;#39;s &lt;strong&gt;Login&lt;/strong&gt; action. While we&amp;#39;re at it, I&amp;#39;ll show you an example of handling multiple exceptions with one sub-filter:&lt;/p&gt;
  1633. &lt;script src=""&gt; &lt;/script&gt;
  1635. &lt;p&gt;Here in line 1 we specify not the name of the view to render, but the name of the action and controller to redirect to (in the format &amp;quot;action,controller&amp;quot;). The handler knows to process this as a redirect because we&amp;#39;ve changed the mode for this one sub-filter to &lt;strong&gt;ErrorHandlerMode.Redirect&lt;/strong&gt;. Lines 7, 8, &amp;amp; 9 illustrate the capability for one sub-filter to match against many exceptions.&lt;/p&gt;
  1637. &lt;h2&gt;Download The Code&lt;/h2&gt;
  1639. &lt;p&gt;I hope you find these filters useful. If they don&amp;#39;t happen to match your particular problem, then feel free to write your own filters. To do so you only have to implement the &lt;strong&gt;IControllerFilter&lt;/strong&gt; interface. I&amp;#39;ve attempted to make it even easier to do so by providing a base class named &lt;strong&gt;ControllerFilter&lt;/strong&gt; that already implements the interface and has several hooks for you to take advantage of.&lt;/p&gt;
  1641. &lt;p&gt;You are free to use or modify this code for anything including commercial purposes. The only restriction I ask is that you do not take credit for this work yourself, but I do not require any specific attribution.&lt;/p&gt;
  1643. &lt;p&gt;I have packaged the code into four different releases:&lt;/p&gt;
  1645. &lt;p class="warning"&gt;These projects were built on Vista x64. If you are running a 32-bit version of Windows you may initially have trouble building the source versions below. To fix this you'll need to re-add the System.Web.Extensions reference. &lt;a href="#comment-152106318"&gt;See my comment below for more details.&lt;/a&gt;&lt;/p&gt;
  1647. &lt;p&gt;*&lt;em&gt;Full Source Release
  1648. *&lt;/em&gt;The entire solution zipped up.
  1649. &lt;a href="/custom/files/old/MVC+Controller+Filters+(Source+and+Example+Website).zip"&gt;MVC+Controller+Filters+(Source+and+Example+Website).zip&lt;/a&gt;&lt;/p&gt;
  1651. &lt;p&gt;&lt;strong&gt;Example Site &amp;amp; Binaries Release&lt;/strong&gt;
  1652. &lt;strong&gt;(Recommended)&lt;/strong&gt; Just the binaries zipped up with an example site.
  1653. &lt;a href="/custom/files/old/MVC+Controller+Filters+(Example+Website).zip"&gt;MVC+Controller+Filters+(Example+Website).zip&lt;/a&gt;&lt;/p&gt;
  1655. &lt;p&gt;&lt;strong&gt;Filter Source Release&lt;/strong&gt;
  1656. The source code for the FilterController and filters. No example site.
  1657. &lt;a href="/custom/files/old/MVC+Controller+Filters+(Source).zip"&gt;MVC+Controller+Filters+(Source).zip&lt;/a&gt;&lt;/p&gt;
  1659. &lt;p&gt;&lt;strong&gt;Filter Binaries Release&lt;/strong&gt;
  1660. The binaries for the FilterController and filters only. No source.
  1661. &lt;a href="/custom/files/old/MVC+Controller+Filters+(Binaries).zip"&gt;MVC+Controller+Filters+(Binaries).zip&lt;/a&gt;&lt;/p&gt;
  1662. &lt;div class="feedflare"&gt;
  1663. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1664. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1665. <feedburner:origLink></feedburner:origLink></entry>
  1666. <entry>
  1667.   <title>MVC Template Fix</title>
  1668.   <link href="" />
  1669.   <updated>2008-01-02T00:00:00+00:00</updated>
  1670.   <id></id>
  1671.   <content type="html">&lt;p&gt;Several weeks ago &lt;a href="/2007/12/11/mvc-bug-broken-codebehind/"&gt;I blogged about a bug&lt;/a&gt; I found in the &lt;a href=""&gt;CTP release of the MVC framework&lt;/a&gt;. The gist of the bug is that controls declared in the html portion of a page or user control could not be referenced from the code-behind of that page or user control. ScottGu posted a comment clarifying that &lt;a href="/2007/12/11/mvc-bug-broken-codebehind/#comment-152106388"&gt;this was due to a bug in the templates&lt;/a&gt; released in the CTP. &lt;/p&gt;
  1673. &lt;p&gt;After nearly a month of following Scott&amp;#39;s advice on how to fix the bug, I finally grew tired of such a repetitive task and have fixed the templates. You&amp;#39;ll find a zip file containing the fix and installation instructions at the bottom of this post. Before I get into that though, let me explain the workaround (suggested by ScottGu) that I&amp;#39;ve been using until now: &lt;/p&gt;
  1675. &lt;h2&gt;The Easy, Repetitive Workaround&lt;/h2&gt;
  1677. &lt;p&gt;The problem is that the template for pages, master pages, and user controls only include the declarative HTML file and it&amp;#39;s code-behind. The template is missing the designer file used by Visual Studio to hide the references generated by the server controls declared in your HTML. Here is what a MVC page looks like right after creation: &lt;/p&gt;
  1679. &lt;p&gt;&lt;img src="/custom/files/old/SimpleWorkaround-Before_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  1681. &lt;p&gt;You could manually create a designer class to fix this issue, but that would be a pain. Luckily Visual Studio provides us with the handy &amp;quot;Convert to Web Application&amp;quot; feature to generate the designer class for us. Simply right-click on the .ASPX (or .Master or .ASCX) and click the &amp;quot;Convert to Web Application&amp;quot; option on the context menu. &lt;/p&gt;
  1683. &lt;p&gt;&lt;img src="/custom/files/old/SimpleWorkaround-During_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  1685. &lt;p&gt;After doing so, you should see this: &lt;/p&gt;
  1687. &lt;p&gt;&lt;img src="/custom/files/old/SimpleWorkaround-After_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  1689. &lt;p&gt;&lt;em&gt;Voil&amp;agrave;&lt;/em&gt;! Your codebehind file for that page/control (and that page/control only) should now work as expected. Its quick and simple, but I&amp;#39;m sure you can imagine already the annoyance at having to do this for each and every page or control you create. That thought leads us to... &lt;/p&gt;
  1691. &lt;h2&gt;The Slightly More Complex Permanent Solution&lt;/h2&gt;
  1693. &lt;p&gt;First, an admission of guilt: I only fixed the C# templates. I apologize to any VB.Net&amp;#39;ers out there ahead of time. &lt;/p&gt;
  1695. &lt;p&gt;There are four templates that must be fixed: &lt;/p&gt;
  1697. &lt;ul&gt;
  1698. &lt;li&gt;View Master Page - A master page.&lt;/li&gt;
  1699. &lt;li&gt;View Page - A normal page.&lt;/li&gt;
  1700. &lt;li&gt;View Content Page - A page that uses a master page.&lt;/li&gt;
  1701. &lt;li&gt;View User Control - A control.&lt;/li&gt;
  1702. &lt;/ul&gt;
  1704. &lt;p&gt;These four templates are found in two different places: the &lt;em&gt;item templates&lt;/em&gt; folder and the item &lt;em&gt;templates cache&lt;/em&gt; folder. &lt;/p&gt;
  1706. &lt;p&gt;Those folders are found at: &amp;quot;&lt;em&gt;Common7IDEItemTemplatesCSharpWeb1033&lt;/em&gt;&amp;quot; and &amp;quot;&lt;em&gt;Common7IDEItemTemplatesCacheCSharpWeb1033&lt;/em&gt;&amp;quot; respectively (within your VS 9 root folder). &lt;/p&gt;
  1708. &lt;p&gt;The item templates folder contains zip files which are at some point unzipped and stored in the item &lt;em&gt;templates cache&lt;/em&gt; folder. I suppose you could just update the contents of the &lt;em&gt;item templates cache&lt;/em&gt; folder, but I don&amp;#39;t know if those settings would ever be written over by the &lt;em&gt;item templates&lt;/em&gt; folder, so it is better to be safe and fix it in both places. &lt;/p&gt;
  1710. &lt;p&gt;&lt;img src="/custom/files/old/TemplateFix-ZipLocation_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  1712. &lt;p&gt;&lt;img src="/custom/files/old/TemplateFix-CacheLocation_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  1714. &lt;p&gt;The contents of a typical template for pages/user controls are: &lt;/p&gt;
  1716. &lt;ul&gt;
  1717. &lt;li&gt;a &lt;em&gt;vtemplate&lt;/em&gt; file (which serves as the manifest for the rest of the items)&lt;/li&gt;
  1718. &lt;li&gt;an icon file&lt;/li&gt;
  1719. &lt;li&gt;an html file (ASPX, ASCX, etc)&lt;/li&gt;
  1720. &lt;li&gt;a codebehind file&lt;/li&gt;
  1721. &lt;li&gt;a designer file&lt;/li&gt;
  1722. &lt;/ul&gt;
  1724. &lt;p&gt;As you can see from the screenshot below, the templates did not include a designer file. &lt;/p&gt;
  1726. &lt;p&gt;&lt;img src="/custom/files/old/TemplateFix-ZipContents_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  1728. &lt;p&gt;In addition, the vtemplate file does not describe a designer file. &lt;/p&gt;
  1730. &lt;p&gt;&lt;img src="/custom/files/old/TemplateFix-TemplateFile_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  1732. &lt;p&gt;The fix is to add a line to the vtemplate file referencing a designer file and then add the designer file itself to the template folder/zip. The designer file should look something like: &lt;/p&gt;
  1734. &lt;p&gt;&lt;img src="/custom/files/old/TemplateFix-DesignerFile_2.jpg" alt="IMAGE"&gt; &lt;/p&gt;
  1736. &lt;p&gt;I&amp;#39;ve gone ahead and done all this for you -- well, actually for me, but you get the point. :-) All you need to do is download the zip file from below and follow the instructions included in the readme.txt file.&lt;/p&gt;
  1738. &lt;p&gt;&lt;a href="/custom/files/old/"&gt;;/a&gt;&lt;/p&gt;
  1739. &lt;div class="feedflare"&gt;
  1740. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1741. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1742. <feedburner:origLink></feedburner:origLink></entry>
  1743. <entry>
  1744.   <title>MVC: ViewData vs. TempData</title>
  1745.   <link href="" />
  1746.   <updated>2007-12-20T00:00:00+00:00</updated>
  1747.   <id></id>
  1748.   <content type="html">&lt;p class="warning"&gt;This article was written for the December CTP release of the MVC framework. Unfortunately, it does not entirely apply to the Preview 2 release or subsequent releases.&lt;/p&gt;
  1750. &lt;p&gt;A commenter (&lt;a href=""&gt;oVan&lt;/a&gt;) recently &lt;a href="/2007/12/10/aspnet-mvc-membership-basics/#comment-152106519"&gt;left a comment&lt;/a&gt; on one of my posts with a suggestion to redirect to a different URL rather than display a different view. He cautioned that if I do so to make certain I use store data in the TempData dictionary rather than ViewData. I had not yet heard of the TempData dictionary, so I set off into &lt;a href=""&gt;Reflector&lt;/a&gt; to find out what exactly it is.&lt;/p&gt;
  1752. &lt;p&gt;Initially it appeared that TempData was simply a Dictionary&amp;lt;string,object&amp;gt; stored in session. This is close to the truth, but not the whole truth. In fact the internal declaration of TempData&amp;#39;s storage device is:&lt;/p&gt;
  1754. &lt;script src=""&gt; &lt;/script&gt;
  1756. &lt;p&gt;Why such a complicated declaration? Further digging revealed that the second element of the pair (the HashSet) is used as a kind of key synchronization device. When an item is added to the internal storage, the key is placed in the HashSet. At some point that I have been unable to determine, the key is removed from the HashSet. Then when the TempData object is built again, the discrepancy is noticed and the Dictionary entry that has a key not contained in the HashSet is removed from the Dictionary.  &lt;/p&gt;
  1758. &lt;p&gt;The end result is that &lt;strong&gt;any data stored in TempData will be around for the life the current request and the next request only&lt;/strong&gt;, or until the item is removed explicitly. This is useful when you want to pass data to another view that you will be redirecting to, rather than rendering to.  &lt;/p&gt;
  1760. &lt;script src=""&gt; &lt;/script&gt;
  1762. &lt;p&gt;In the code above if you navigate to the Index page, you are automatically redirected to the Test1 action&amp;#39;s URL. The Test1 action then executes and is able to access the data stored for it in TempData. If you then navigate to the Test2 action, that action is unable to retrieve the data previously stored in TempData.&lt;/p&gt;
  1764. &lt;p&gt;To retrieve data from TempData inside of a view, do the following:&lt;/p&gt;
  1766. &lt;script src=""&gt; &lt;/script&gt;
  1768. &lt;p&gt;One suggestion for an improvement in the next CTP would be to have all data available in TempData copied over to ViewData at the beginning of a request (after the old TempData has been cleared). This would allow us to simply say:&lt;/p&gt;
  1770. &lt;script src=""&gt; &lt;/script&gt;
  1772. &lt;p&gt;Otherwise the view has to be very aware of the controller and how it plans to pass data into the view. Currently I cannot have a view that supports being passed data both ways without doing the following:  &lt;/p&gt;
  1774. &lt;script src=""&gt; &lt;/script&gt;
  1775. &lt;div class="feedflare"&gt;
  1776. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1777. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1778. <feedburner:origLink></feedburner:origLink></entry>
  1779. <entry>
  1780.   <title>MVC Complaint: Checkboxes</title>
  1781.   <link href="" />
  1782.   <updated>2007-12-11T00:00:00+00:00</updated>
  1783.   <id></id>
  1784.   <content type="html">&lt;p class="warning"&gt;This article was written for the December CTP release of the MVC framework. Unfortunately, it does not entirely apply to the Preview 2 release or subsequent releases.&lt;/p&gt;
  1786. &lt;p&gt;I mentioned in my previous post on &lt;a href="/2007/12/10/aspnet-mvc-membership-basics/"&gt;building login &amp;amp; registration forms&lt;/a&gt; in the &lt;a href=""&gt;ASP.NET MVC framework&lt;/a&gt; that I was not a fan of the way checkboxes are handled in the first CTP release&amp;#39;s &lt;a href=""&gt;toolkit&lt;/a&gt;. To help explain why I don&amp;#39;t care for it, consider the following... what would you expect the following helper function to output?&lt;/p&gt;
  1788. &lt;script src=""&gt; &lt;/script&gt;
  1790. &lt;p&gt;I would imagine a single checkbox and a label with the text value, which is incorrect. Instead, this is what is generated:&lt;/p&gt;
  1792. &lt;script src=""&gt; &lt;/script&gt;
  1794. &lt;p&gt;It looks fairly reasonable to most and really isn&amp;#39;t the end of the world, but is rather unusable in my eyes. The text is just output inline directly following the checkbox element with no element wrapping it. This small omission makes it incredibly difficult to style the output effectively using CSS. Simply wrap the text in a &amp;lt;label&amp;gt; element and everything is gravy. What I would prefer to see output is:&lt;/p&gt;
  1796. &lt;script src=""&gt; &lt;/script&gt;
  1798. &lt;p&gt;I realize this seems like a nitpick; I&amp;#39;m perfectly capable of writing my own HTML checkbox and label (usually). My frustrations do not end there, though; let&amp;#39;s look at how you retrieve data from a checkbox within a controller action that you have posted to. Taking the example of a simple login form with two text fields (&amp;quot;userName&amp;quot; and &amp;quot;password&amp;quot;) and one checkbox (&amp;quot;rememberMe&amp;quot;) you might expect to have the following controller action:&lt;/p&gt;
  1800. &lt;script src=""&gt; &lt;/script&gt;
  1802. &lt;p&gt;Given the context of this article, you can probably guess that the above doesn&amp;#39;t work. Unfortunately the automagic code that maps fields found in the HTTP request to parameters in a controller action does not support mapping to a boolean. This is partly the fault of the HTTP spec (submitting a checked checkbox causes the form to post with $NAME=$VALUE where $NAME is the name of the checkbox element and $VALUE is the value of the &amp;quot;value&amp;quot; attribute; submitting an unchecked checkbox causes the form to post without any reference to the checkbox -- i.e.: a null value), but could easily be resolved with the following rule:&lt;/p&gt;
  1804. &lt;p&gt;&lt;strong&gt;When a boolean is declared in a method marked with [ControllerAction], pass false into the parameter unless a text value is found with a field name that correlates to the name of the parameter (in which case pass true).&lt;/strong&gt;&lt;/p&gt;
  1806. &lt;p&gt;In other words, if you can&amp;#39;t find a mention of &amp;quot;rememberMe&amp;quot; in the form&amp;#39;s POST data, pass false to the parameter. If the form&amp;#39;s POST data contains *any *value for a field named &amp;quot;rememberMe,&amp;quot; pass true to the parameter. For the time being you should declare the checkbox parameter as a string and test it against null, like so:&lt;/p&gt;
  1808. &lt;script src=""&gt; &lt;/script&gt;
  1810. &lt;p&gt;Sure, it isn&amp;#39;t rocket science the way it is setup right now, but a little extra work could make for a much more fluid learning curve for new MVC developers. Obviously this is just a CTP release and not the full deal; I fully expect a lot of these quirks to be worked out over the next several months. This does make me wonder, will the toolkit be posted to &lt;a href=""&gt;CodePlex&lt;/a&gt; so that it can benefit from community involvement?&lt;/p&gt;
  1811. &lt;div class="feedflare"&gt;
  1812. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1813. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1814. <feedburner:origLink></feedburner:origLink></entry>
  1815. <entry>
  1816.   <title>MVC Bug: Broken Codebehind</title>
  1817.   <link href="" />
  1818.   <updated>2007-12-11T00:00:00+00:00</updated>
  1819.   <id></id>
  1820.   <content type="html">&lt;p class="warning"&gt;This post is no longer relevant with recent releases of ASP.NET MVC.&lt;/p&gt;
  1822. &lt;p&gt;&lt;strong&gt;Update (Jan 2):&lt;/strong&gt; I have posted &lt;a href="/2008/01/02/mvc-template-fix/"&gt;a permanent fix in the form of modified Visual Studio templates in another blog post&lt;/a&gt;.&lt;/p&gt;
  1824. &lt;p&gt;&lt;strong&gt;Update (Dec 11):&lt;/strong&gt; ScottGu was kind enough to &lt;a href="#comment-152106388"&gt;post a fix for this particular problem&lt;/a&gt;. It is unfortunate that you have to repeat the fix for every view you add to your project, but I guess that&amp;#39;s why it is called a CTP! ScottGu said... &lt;/p&gt;
  1826. &lt;blockquote&gt;
  1827. There is a bug in the file template when you create a new page - and the .designer.cs file isn't generated.
  1829. To fix this, right click on the file and choose the "Convert to Web Application" menu item. This will generate the .designer.cs file that contains your control declarations. From that point on the code-behind will be kept up to date as you make changes.
  1831. Hope this helps,
  1833. Scott
  1834. &lt;/blockquote&gt;
  1836. &lt;p&gt;&lt;strong&gt;Original Post:&lt;/strong&gt;&lt;/p&gt;
  1838. &lt;p&gt;It may not be a popular choice, but I&amp;#39;m perfectly okay with in-line code in my views as long as it doesn&amp;#39;t contain business logic. One of the developers on my project prefers tag-based views (&amp;lt;asp:Blah runat=&amp;quot;server&amp;quot; /&amp;gt;) and came to me yesterday with a curious issue. I&amp;#39;ve spent some of the morning investigating the issue and it does appear that there is a bug in the &lt;a href=""&gt;newly released ASP.Net MVC Framework&lt;/a&gt;.&lt;/p&gt;
  1840. &lt;p&gt;The issue? &lt;strong&gt;Controls declared in an ASPX are not visible to that page&amp;#39;s codebehind.&lt;/strong&gt;&lt;/p&gt;
  1842. &lt;p&gt;To test this hypothesis (and make sure we hadn&amp;#39;t somehow broken our project) I started a new &amp;quot;ASP.Net MVC Web Application&amp;quot; project (note that the bug also exists for the &amp;quot;ASP.Net MVC Web Application and Test&amp;quot; project). I then opened the Views/Home/About.aspx file and added the following line:&lt;/p&gt;
  1844. &lt;script src=""&gt; &lt;/script&gt;
  1846. &lt;p&gt;Then I opened up the page&amp;#39;s codebehind (Views/Home/About.aspx.cs) and added the following:&lt;/p&gt;
  1848. &lt;script src=""&gt; &lt;/script&gt;
  1850. &lt;p&gt;Ctrl+Shift+B to compile and bam, a build error: &lt;strong&gt;&amp;quot;The name &amp;#39;myLiteral&amp;#39; does not exist in the current context.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
  1852. &lt;p&gt;I began to wonder if this was not supported by the MVC framework, but I took a look back at one of ScottGu&amp;#39;s most recent articles, &lt;a href=""&gt;ASP.Net MVC Framework (Part 3): Passing ViewData from Controllers to Views&lt;/a&gt;, and saw that he references controls from the page&amp;#39;s codebehind several times. I also tried using several controls besides the Literal to no avail. &lt;/p&gt;
  1854. &lt;p&gt;To test what was going on, I commented out the reference in the Page_Load method, added a string declaration and put a breakpoint on it. When I ran the MVC application in debug mode and loaded the page I was able to see the &amp;quot;myLiteral&amp;quot; control reference. It appears that the reference is available at runtime but Visual Studio just is not able to see it at compile time. Odd. &lt;/p&gt;
  1856. &lt;p&gt;&lt;img src="/custom/files/old/DebugMyLiteral.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  1858. &lt;p&gt;For now I&amp;#39;ve told the developer to just use in-line code, but I&amp;#39;m well aware that many developers are loathe to do so. Thoughts? Suggestions?&lt;/p&gt;
  1859. &lt;div class="feedflare"&gt;
  1860. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1861. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1862. <feedburner:origLink></feedburner:origLink></entry>
  1863. <entry>
  1864.   <title>ASP.Net MVC Membership Basics</title>
  1865.   <link href="" />
  1866.   <updated>2007-12-10T00:00:00+00:00</updated>
  1867.   <id></id>
  1868.   <content type="html">&lt;p class="warning"&gt;This article was written for the December 2007 CTP release of the MVC framework. It does not entirely apply to the Preview 2 release or subsequent releases.&lt;/p&gt;
  1870. &lt;p&gt;&lt;a href=""&gt;The MVC bits have finally arrived&lt;/a&gt; and I&amp;#39;ve spent a while digesting them. I&amp;#39;ve been waiting for the bits to be released to begin working on a side-project, so the first thing I did after downloading them last night was crank it up and start working on a new ASP.NET MVC Web Application project.&lt;/p&gt;
  1872. &lt;p&gt;Typically, the first thing I do on a new project is set up the authentication/authorization system. For the project I am working on I want to use the ASP.Net Membership system, but most of the Membership controls do not work with the MVC framework because they require postbacks. I spent some time last night building a Security controller and views for Registration and Login that I thought would be worth sharing.&lt;/p&gt;
  1874. &lt;p&gt;So far I have implemented basic functionality for Register, Login, and Logout. There are three files we will have to create. We will also have to change the routing table. Let&amp;#39;s start with the SecurityController:&lt;/p&gt;
  1876. &lt;script src=""&gt; &lt;/script&gt;
  1878. &lt;p&gt;So we have two basic actions methods that only display views (Register and Login) and three action-only methods that have no views (CreateUser, Authenticate, Logout).&lt;/p&gt;
  1880. &lt;p&gt;I have chosen to not have a logout page, but to instead redirect to the homepage. Switch out &amp;#39;Response.Redirect( &amp;quot;/&amp;quot; );&amp;#39; for &amp;#39;RenderView( &amp;quot;Logout&amp;quot; );&amp;#39; and create a Logout.aspx view if you would like to display a logout message.&lt;/p&gt;
  1882. &lt;p&gt;Now let&amp;#39;s look at the Login view:&lt;/p&gt;
  1884. &lt;script src=""&gt; &lt;/script&gt;
  1886. &lt;p&gt;The toolkit&amp;#39;s Html.Checkbox(...) method annoys me. More on why in another post. For now I&amp;#39;ve instead just written the html out by hand. You&amp;#39;ll note I&amp;#39;ve also linked the label to the checkbox with JavaScript so that clicking the label toggles the checkbox.&lt;/p&gt;
  1888. &lt;p&gt;Then the Register view:&lt;/p&gt;
  1890. &lt;script src=""&gt; &lt;/script&gt;
  1892. &lt;p&gt;Another straightforward view. Not much to discuss here.&lt;/p&gt;
  1894. &lt;p&gt;And finally, let&amp;#39;s add the new routes:&lt;/p&gt;
  1896. &lt;script src=""&gt; &lt;/script&gt;
  1898. &lt;p&gt;I personally like login to be &amp;quot;http://website/login&amp;quot; and register to be &amp;quot;http://website/register&amp;quot;, so that is how I have configured it. The other three actions (Logout, Authenticate, and CreateUser) I access via the default route (ex: /Security/Logout).&lt;/p&gt;
  1900. &lt;p&gt;That&amp;#39;s it! You should now have a working registration/login system. I&amp;#39;ll leave making it pretty with CSS as an exercise for the reader.&lt;/p&gt;
  1902. &lt;p&gt;I have included all of the code samples above in the below ZIP file. Just unzip it and place the controller into the Controllers directory, the views into the Views/Security directory (which you will have to create), and copy the code from Routes.txt to the appropriate area of your Global.asax.&lt;/p&gt;
  1904. &lt;p&gt;&lt;a href="/custom/files/old/"&gt;;/a&gt;&lt;/p&gt;
  1906. &lt;p&gt;&lt;a name="update-dec-11"&gt;&lt;/a&gt;
  1907. &lt;strong&gt;UPDATE (Dec 11):&lt;/strong&gt; Johan and &lt;a href=""&gt;Steve Harman&lt;/a&gt; were kind enough to &lt;a href="#comment-152106495"&gt;point out&lt;/a&gt; that I had foolishly set the &amp;quot;remember me&amp;quot; checkbox&amp;#39;s label&amp;#39;s &amp;quot;for&amp;quot; attribute to point to the password field instead of the checkbox itself. I have fixed the code above and provided a new zip file (1.1) for download. Thanks guys!&lt;/p&gt;
  1909. &lt;p&gt;&lt;a name="update-dec-19"&gt;&lt;/a&gt;
  1910. &lt;strong&gt;Update (Dec 19):&lt;/strong&gt; &lt;a href=""&gt;oVan&lt;/a&gt; &lt;a href="#comment-152106514"&gt;pointed out a bug&lt;/a&gt; in the routing rules defined in the routes.txt file. I have updated the zip file with the correct code. Thanks oVan!&lt;/p&gt;
  1912. &lt;p&gt;&lt;a name="update-jan-3"&gt;&lt;/a&gt;
  1913. &lt;strong&gt;Update (Jan 3):&lt;/strong&gt; &lt;a href="#comment-152106536"&gt;James Nail asked a very good question via a comment&lt;/a&gt;: what do you set for the loginUrl and defaultUrl in your web.config? Well James, here is how I&amp;#39;ve setup my web.config...&lt;/p&gt;
  1915. &lt;p&gt;Assuming we&amp;#39;ll be using forms authentication and securing all pages except login and the homepage, place the following inside the &amp;lt;system.web&amp;gt; element:&lt;/p&gt;
  1917. &lt;script src=""&gt; &lt;/script&gt;
  1919. &lt;p&gt;Then, somewhere outside the &amp;lt;system.web&amp;gt; element add:&lt;/p&gt;
  1921. &lt;script src=""&gt; &lt;/script&gt;
  1923. &lt;p&gt;Note that this will grant access to all actions within the Security controller. It is also worth pointing out that, dependent on your setup, your CSS and image files may not load unless you also create a location path for their directory and grant all users access like so:&lt;/p&gt;
  1925. &lt;script src=""&gt; &lt;/script&gt;
  1927. &lt;p&gt;I have not updated the zip file with these web.config settings; let me know if anyone would prefer that I add it. I hope this helps some of you!&lt;/p&gt;
  1928. &lt;div class="feedflare"&gt;
  1929. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1930. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1931. <feedburner:origLink></feedburner:origLink></entry>
  1932. <entry>
  1933.   <title> Release TODAY!</title>
  1934.   <link href="" />
  1935.   <updated>2007-12-09T00:00:00+00:00</updated>
  1936.   <id></id>
  1937.   <content type="html">&lt;p&gt;Scott Guthrie posted a comment to his &lt;a href=""&gt;fourth entry in his ASP.Net MVC tutorial series&lt;/a&gt; stating: &lt;/p&gt;
  1939. &lt;blockquote&gt;
  1940. Sunday, December 09, 2007 8:00 AM by ScottGu
  1941. Hi Panjkov,
  1943. &gt;&gt;&gt;&gt;&gt;&gt; is this correct link for extensions preview that will be shipped (today?) (taken from )
  1945. No - that is for the ADO.NET entities bits (which is something different).  Keep an eye on in a few hours - the ASP.NET 3.5 Extensions Preview (which includes MVC) will be posted there shortly.
  1947. Thanks,
  1949. Scott
  1950. &lt;/blockquote&gt;
  1952. &lt;p&gt;This is great news and rather unexpected. Time to hit up &lt;a href=""&gt;;/a&gt; and F5 F5 F5...! &lt;/p&gt;
  1954. &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; As everyone is aware by now, I&amp;#39;m sure, the MVC Framework has been released. You can &lt;a href=""&gt;get it here&lt;/a&gt;.&lt;/p&gt;
  1955. &lt;div class="feedflare"&gt;
  1956. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1957. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1958. <feedburner:origLink></feedburner:origLink></entry>
  1959. <entry>
  1960.   <title>MVC Framework Delayed</title>
  1961.   <link href="" />
  1962.   <updated>2007-12-07T00:00:00+00:00</updated>
  1963.   <id></id>
  1964.   <content type="html">&lt;p&gt;&lt;a href=""&gt;ScottGu has posted a comment&lt;/a&gt; on his latest blog post saying that a last minute bug has delayed the release of the new .Net MVC Framework, which was previously slated for release today in the form of a CTP. From the sound of things we are now looking at a Monday release if further testing does not reveal any further issues. &lt;/p&gt;
  1966. &lt;p&gt;I&amp;#39;m sure I speak for almost all of us that are awaiting this highly anticipated release when I say that all of their hard work is appreciated and while the delay is disappointing, what is a few more days? The full text of Scott&amp;#39;s comment is below: &lt;/p&gt;
  1968. &lt;blockquote&gt;
  1970. Quick update to everyone - we found a last minute bug late last night, and had to-do a rebuild of the bits. This unfortunately means we won't go live today as originally planned. The team is working hard, though, to try and get it out ASAP (they will be here this weekend finishing the test pass).
  1972. I'll do a blog post announcing it as soon as it is live. As penance I'm also doing a long Part 4 blog post this weekend that covers editing and form posting scenarios, which combined with the first three tutorial posts should provide a pretty good foundation for working with the bits.
  1974. Many apologies for the delay - almost there now though,
  1976. Scott
  1977. &lt;/blockquote&gt;
  1978. &lt;div class="feedflare"&gt;
  1979. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  1980. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  1981. <feedburner:origLink></feedburner:origLink></entry>
  1982. <entry>
  1983.   <title> 1.2.5 Scrapped</title>
  1984.   <link href="" />
  1985.   <updated>2007-12-07T00:00:00+00:00</updated>
  1986.   <id></id>
  1987.   <content type="html">&lt;p&gt;Apparently this just isn&amp;#39;t my day when it comes to project released that I&amp;#39;ve been looking forward to. &lt;a href=""&gt;Mads Kristensen&lt;/a&gt; posted to the &lt;a href=""&gt; project&amp;#39;s website&lt;/a&gt; stating that &lt;a href=""&gt;the 1.2.5 release of the project (a service pack, really) will no longer happen&lt;/a&gt; and that all of its changes will be rolled into a 1.3 release, due before the end of the year. &lt;/p&gt;
  1989. &lt;p&gt;Disappointing, yes, but really for the best. The 1.2.5 release fixed quite a few bugs, but none of them show stoppers (well, for me) and 1.3 looks to add some new features to the equation. &lt;/p&gt;
  1991. &lt;h2&gt;Coming in 1.3:&lt;/h2&gt;
  1993. &lt;ul&gt;
  1994. &lt;li&gt;Full mono support (right out of the box)&lt;/li&gt;
  1995. &lt;li&gt;Updated Meta-Weblog API including support for creating/editing pages in WLW&lt;/li&gt;
  1996. &lt;li&gt;Improved Blog importer/exporter, including support for easily switching between XML and SQL backends &lt;/li&gt;
  1997. &lt;li&gt;New extension manager to managing extensions and their settings&lt;/li&gt;
  1998. &lt;li&gt;New events for extension writers&lt;/li&gt;
  1999. &lt;li&gt;Support for mobile devices&lt;/li&gt;
  2000. &lt;li&gt;New themes&lt;/li&gt;
  2001. &lt;/ul&gt;
  2003. &lt;p&gt;I&amp;#39;m especially looking forward to the mobile device support and further Live Writer integration. &lt;/p&gt;
  2004. &lt;div class="feedflare"&gt;
  2005. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  2006. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  2007. <feedburner:origLink></feedburner:origLink></entry>
  2008. <entry>
  2009.   <title>GraffitiCMS Beta Opens</title>
  2010.   <link href="" />
  2011.   <updated>2007-12-05T00:00:00+00:00</updated>
  2012.   <id></id>
  2013.   <content type="html">&lt;p class="warning"&gt;GraffitiCMS appears to be effectively dead now, and has been released to the community. You can still &lt;a href=""&gt;find the code on CodePlex.&lt;/a&gt;&lt;/p&gt;
  2015. &lt;p&gt;&lt;a href=""&gt;GraffitiCMS&lt;/a&gt; (from &lt;a href=""&gt;Telligent&lt;/a&gt;, makers of &lt;a href=""&gt;Community Server&lt;/a&gt;) has been released in beta. Head on over to their &lt;a href=""&gt;official site&lt;/a&gt; to download it. &lt;/p&gt;
  2016. &lt;div class="feedflare"&gt;
  2017. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  2018. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  2019. <feedburner:origLink></feedburner:origLink></entry>
  2020. <entry>
  2021.   <title>Add/Update/Delete with LINQPad</title>
  2022.   <link href="" />
  2023.   <updated>2007-12-05T00:00:00+00:00</updated>
  2024.   <id></id>
  2025.   <content type="html">&lt;p&gt;&lt;a href=""&gt;Danny Douglass&lt;/a&gt; recently &lt;a href=""&gt;posted&lt;/a&gt; about &lt;a href=""&gt;LINQPad&lt;/a&gt;, a query tool that understands LINQ. I spent some time today using it and am very impressed. It did take a while, however, to look through the numerous sample scripts and figure out exactly how to insert/update/delete data, so I thought I would share what I&amp;#39;ve found. The biggest changes between working in LINQ-To-SQL in a Visual Studio 2008 project and writing a LINQ query in LINQPad are the lack of a &lt;strong&gt;DataContext, *&lt;em&gt;the difference between *&lt;/em&gt;C# Expressions&lt;/strong&gt; and &lt;strong&gt;C# Statements&lt;/strong&gt;, and the addition of a &lt;strong&gt;Dump&lt;/strong&gt; command. &lt;/p&gt;
  2027. &lt;p&gt;&lt;strong&gt;No Data Context:&lt;/strong&gt; When you need to interact with a database via LINQ in a Visual Studio 2008 project, you do so by creating a LINQ-To-SQL DBML file that generates a data context for you. This data context is in charge of maintaining your database connection and is what you use to submit changes to the database. Because there is no data context readily available to you (and no .dbml file) in LINQPad, the way you go about this is slightly different. There is a globally-scoped subroutine, &amp;quot;SubmitChanges(),&amp;quot; that should be called whenever you wish to commit an action to the database. &lt;/p&gt;
  2029. &lt;p&gt;&lt;strong&gt;C# Expressions vs. C# Statements:&lt;/strong&gt; By default LINQPad opens in &amp;quot;C# Expression&amp;quot; mode. In this mode you can type a simple query like &amp;quot;from r in Regions select r&amp;quot; and run it to see the results. As far as I can tell there is no way to insert/update/delete data in this mode. By switching to &amp;quot;C# Statement(s)&amp;quot; mode you are able to declare variables, control flow statements, and reference objects; this is the mode you need to be in to insert/update/delete data. To enter &amp;quot;C# Statement(s)&amp;quot; mode, select it from the &amp;quot;Type&amp;quot; drop-down box at the top of the window as show below: &lt;/p&gt;
  2031. &lt;p&gt;&lt;img src="/custom/files/old/LINQPad_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  2033. &lt;p&gt;&lt;strong&gt;object.Dump():&lt;/strong&gt; When you write a query in &amp;quot;C# Expression&amp;quot; mode the result of that query is automatically rendered to the Results frame (shown below). Because &amp;quot;C# Statement(s)&amp;quot; mode gives you the capability to run many queries in one execute, displaying the results of those queries must be manually invoked. To do so simply call the &amp;quot;.Dump()&amp;quot; method on the resultset of the query you want to display. &amp;quot;.Dump()&amp;quot; is implemented as an extension method available on all objects, so whether you are retrieving a single object, a list of objects, or an anonymous type the Dump method will be available to display your data. &lt;/p&gt;
  2035. &lt;p&gt;&lt;img src="/custom/files/old/LINQPad-Results_2.jpg" alt="IMAGE"&gt;&lt;/p&gt;
  2037. &lt;p&gt;Below I have included examples of several ways to query data, as well as an example each for inserting, updating, and deleting data. &lt;/p&gt;
  2039. &lt;script src=""&gt; &lt;/script&gt;
  2040. &lt;div class="feedflare"&gt;
  2041. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  2042. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  2043. <feedburner:origLink></feedburner:origLink></entry>
  2044. <entry>
  2045.   <title>CssHandler: CSS + Variables</title>
  2046.   <link href="" />
  2047.   <updated>2007-11-16T00:00:00+00:00</updated>
  2048.   <id></id>
  2049.   <content type="html">&lt;p class="warning"&gt;Please don't consider using this project anymore - it is old and out of date. &lt;a href=""&gt;Use something like SASS or LESS instead.&lt;/a&gt;&lt;/p&gt;
  2051. &lt;p&gt;It&amp;#39;s been more than three and a half years since &lt;a href=""&gt;Rory Blyth&lt;/a&gt; said &lt;a href=""&gt;&amp;quot;screw standards - let&amp;#39;s add variable support to CSS right this minute.&amp;quot;&lt;/a&gt; In retrospect, adding variables to CSS seems obvious; &lt;a href=""&gt;everyone is asking about it&lt;/a&gt;. There have even been &lt;a href=""&gt;one&lt;/a&gt; or &lt;a href=""&gt;two&lt;/a&gt; other .Net solutions developed, though Rory&amp;#39;s solution has remained my favorite. With CSS2 barely working and &lt;a href=""&gt;CSS3 not addressing the issue&lt;/a&gt;, those of us who are tired of repeating ourselves throughout our CSS files have no choice but to take matters into our own hands.&lt;/p&gt;
  2053. &lt;p&gt;With that in mind I set out to update Rory&amp;#39;s code. Not that there was anything wrong with it in the first place, of course (this is where I try to tactfully avoid being drawn as a jerkasaurus in one of Rory&amp;#39;s comics), but Rory did whip the code up for a &lt;a href=""&gt;PADNUG&lt;/a&gt; meeting and that &lt;em&gt;was&lt;/em&gt; about 3.5 million years ago (give or take many orders of magnitude). It was time to bring the CssHandler into 2007! Conveniently right before 2008.&lt;/p&gt;
  2055. &lt;p&gt;Lo and behold, someone else had beat me to it. &lt;a href=""&gt;Gabe Moothart&lt;/a&gt; had already &lt;a href=""&gt;uploaded the CssHandler to CodePlex&lt;/a&gt;, and even improved upon it. While Rory&amp;#39;s code originally only allowed variable declarations &amp;amp; references and stripped comments, Gabe&amp;#39;s version also resolved application-relative paths (e.g.: &amp;quot;~/blah/blah.gif&amp;quot;) into browser friendly paths. I had further goals in mind though, and Gabe was kind enough to add me onto the project.&lt;/p&gt;
  2057. &lt;p&gt;With my updates complete, I am now proud to present...&lt;/p&gt;
  2059. &lt;h2&gt;CssHandler 1.0&lt;/h2&gt;
  2061. &lt;p&gt;&lt;em&gt;Features&lt;/em&gt;:&lt;/p&gt;
  2063. &lt;ul&gt;
  2064. &lt;li&gt;Define variables for later reference.&lt;/li&gt;
  2065. &lt;li&gt;Resolve application relative paths.&lt;/li&gt;
  2066. &lt;li&gt;Only link to one CSS file from your HTML page. Let the CssHandler combine additional CSS files at runtime to limit HTTP connections and share variable definitions across files.&lt;/li&gt;
  2067. &lt;li&gt;All comments are stripped before render.&lt;/li&gt;
  2068. &lt;li&gt;Most white-space is stripped before render.&lt;/li&gt;
  2069. &lt;li&gt;HttpHandler can be mapped to &amp;#39;*.css&amp;#39; or can be referenced as CssHandler.axd and passed a CSS file in the query string.&lt;/li&gt;
  2070. &lt;/ul&gt;
  2072. &lt;p&gt;&lt;em&gt;Bugs fixed:&lt;/em&gt;&lt;/p&gt;
  2074. &lt;ul&gt;
  2075. &lt;li&gt;The @define{...} block is no longer sent down to the client.&lt;/li&gt;
  2076. &lt;li&gt;Similarly named variables no longer present a problem.&lt;/li&gt;
  2077. &lt;/ul&gt;
  2079. &lt;p&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/p&gt;
  2081. &lt;p&gt;The HTML references &amp;quot;styles.css&amp;quot;, which looks like:&lt;/p&gt;
  2083. &lt;script src=""&gt; &lt;/script&gt;
  2085. &lt;p&gt;As seen above, &amp;quot;styles.css&amp;quot; references &amp;quot;styles2.css&amp;quot; via the @import statement, which looks like:&lt;/p&gt;
  2087. &lt;script src=""&gt; &lt;/script&gt;
  2089. &lt;p&gt;The CssHandler then:&lt;/p&gt;
  2091. &lt;ol&gt;
  2092. &lt;li&gt;Intercepts the browser&amp;#39;s request for &amp;quot;styles.css&amp;quot;.&lt;/li&gt;
  2093. &lt;li&gt;Resolves the two URLs that are using application relative paths.&lt;/li&gt;
  2094. &lt;li&gt;Replaces the @import directive with the text from &amp;quot;styles2.css&amp;quot;.&lt;/li&gt;
  2095. &lt;li&gt;Strips all comments from the CSS.&lt;/li&gt;&lt;/li&gt;
  2096. &lt;li&gt;Replaces all referenced variables with their defined values.&lt;/li&gt;
  2097. &lt;li&gt;Compresses most of the CSS&amp;#39;s white-space.&lt;/li&gt;
  2098. &lt;li&gt;Renders the following to the browser:&lt;/li&gt;
  2099. &lt;/ol&gt;
  2101. &lt;script src=""&gt; &lt;/script&gt;
  2103. &lt;p&gt;I hope you find it as useful as I have. Many thanks to Rory Blyth and Gabe Moothart. Hopefully CSS4 will add variables and we&amp;#39;ll never have to use this again!&lt;/p&gt;
  2105. &lt;p&gt;&lt;a href=""&gt;Visit the project&amp;#39;s CodePlex site to download&lt;/a&gt;.&lt;/p&gt;
  2107. &lt;p&gt;&lt;strong&gt;Update (Dec. 2, 2007):&lt;/strong&gt; Rory has posted and &lt;a href=""&gt;given his blessing&lt;/a&gt;, so to speak. Thanks Rory!&lt;/p&gt;
  2108. &lt;div class="feedflare"&gt;
  2109. &lt;a href=""&gt;&lt;img src="" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
  2110. &lt;/div&gt;&lt;img src="" height="1" width="1" alt=""/&gt;</content>
  2111. <feedburner:origLink></feedburner:origLink></entry>
  2113. </feed>

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid Atom 1.0" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda