<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Jay Harris is Cpt. LoadTest - MVC</title>
    <link>http://www.cptloadtest.com/</link>
    <description>a .net developers blog on improving user experience of humans and coders</description>
    <language>en-us</language>
    <copyright>Jason Harris</copyright>
    <lastBuildDate>Sun, 23 May 2010 22:40:39 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.12105.0</generator>
    <managingEditor>jharris@harrisdesigns.com</managingEditor>
    <webMaster>jharris@harrisdesigns.com</webMaster>
    <item>
      <trackback:ping>http://www.cptloadtest.com/Trackback.aspx?guid=15ae3174-d0bd-4639-9d9c-10d2feeaab35</trackback:ping>
      <pingback:server>http://www.cptloadtest.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.cptloadtest.com/PermaLink,guid,15ae3174-d0bd-4639-9d9c-10d2feeaab35.aspx</pingback:target>
      <dc:creator>Jay Harris</dc:creator>
      <wfw:comment>http://www.cptloadtest.com/CommentView,guid,15ae3174-d0bd-4639-9d9c-10d2feeaab35.aspx</wfw:comment>
      <wfw:commentRss>http://www.cptloadtest.com/SyndicationService.asmx/GetEntryCommentsRss?guid=15ae3174-d0bd-4639-9d9c-10d2feeaab35</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
"There was a time when everything was moving towards the desktop. This Internet
thing was new and cool, but there was no way it would ever last. And no one knew how
to code for the web, at least not anything beyond animated lava lamps and cute "Under
Construction" images. So, to make coding for the web easier, they made ASP.NET
to be just like coding for a desktop, using the same patterns, the same event-based
model, and the same stateful approach. But the web isn't stateful, its only events
are GET and POST, and is nothing like a desktop, so we tortured ourselves for years
forcing a square peg through a round hole. The time has come for redemption, and its
name is ASP.NET MVC. Spend an hour discovering how coding for the web is supposed
to be--how it is today--and end your misery. Salvation awaits."
</p>
        <div style="text-align: center">
          <div style="margin: 0px auto; width: 425px" id="__ss_4091487">
            <object id="__sse4091487" width="425" height="355">
              <param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=asp-netmvc-awebcoderssalvationslideshare-100513220448-phpapp02&amp;stripped_title=aspnet-mvc-2-a-microsoft-web-coders-salvation-4091487" />
              <param name="allowFullScreen" value="true" />
              <param name="allowScriptAccess" value="always" />
              <embed name="__sse4091487" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=asp-netmvc-awebcoderssalvationslideshare-100513220448-phpapp02&amp;stripped_title=aspnet-mvc-2-a-microsoft-web-coders-salvation-4091487" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355">
              </embed>
            </object>
          </div>
          <a title="Slides for &quot;ASP.NET MVC 2: A (Microsoft) Web Coder's Salvation&quot; on SlideShare" href="http://www.slideshare.net/jayharris/aspnet-mvc-2-a-microsoft-web-coders-salvation-4091487">Slides
on SlideShare</a> | <a title="Learn to Code ASP.NET MVC 2 : Introduction to ASP.NET MVC 2" href="http://www.cptloadtest.com/2010/02/23/Learn-To-Code-ASPNET-MVC-2-Introduction-To-ASPNET-MVC-2.aspx">Code
Walkthrough</a></div>
        <p>
At various user groups throughout Southeast Michigan and Northwest Ohio, I have been
presenting this topic since the last quarter of 2009. For those that are interested,
I have made the slide deck available on SlideShare. The code demo used during the
talk is available as a walkthrough via one of my installments of Learn to Code, where
you can create, step-by-step, the same ASP.NET MVC 2 application as was built during
the presentation.
</p>
        <p>
If you attend one of my presentations for this topic, I would appreciate your feedback.
If you are willing to tolerate a small registration process, SpeakerRate will allow
you to give feedback and anonymous ratings to the session you attended. If you are
interested in having me present this topic at your user group or conference, please
contact me.
</p>
        <h3>Past presentations on this topic: 
</h3>
        <p>
          <a title="Rate my ASP.NET MVC 2 Talk at AADND, May 2010" href="http://speakerrate.com/talks/3235-asp-net-mvc-2-a-microsoft-web-coder-s-salvation">Rate</a> –
Ann Arbor .NET Developers, Ann Arbor, Michigan, May 2010 
<br /><a title="Rate my ASP.NET MVC 2 Talk from GLUGnet Lansing, March 2010" href="http://speakerrate.com/talks/2865-asp-net-mvc-2-a-microsoft-web-coder-s-salvation">Rate</a> –
GLUGnet, Lansing, Michigan, March 2010 
<br /><a title="Rate my ASP.NET MVC 2 Talk at A2&lt;DIV&gt;, February 2010" href="http://speakerrate.com/talks/2175-asp-net-mvc-2-a-microsoft-web-coder-s-salvation">Rate</a> –
A2&lt;DIV&gt;, Ann Arbor, Michigan, February 2010 
<br /><a title="Rate my ASP.NET MVC 2 Talk at NWNUG, February 2010" href="http://speakerrate.com/talks/2134-asp-net-mvc-2-a-microsoft-web-coder-s-salvation">Rate</a> –
NWNUG, Toledo, Ohio, February 2010 
<br /><a title="Rate my ASP.NET MVC 2 Talk at GLUGnet Flint, February 2010" href="http://speakerrate.com/talks/3327-asp-net-mvc-2-a-microsoft-web-coder-s-salvation">Rate</a> –
GLUGnet, Flint, Michigan, February 2010
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:97df05d2-ed4c-49b3-af36-91ee1db68b2a" class="wlWriterEditableSmartContent">Technorati
Tags: <a href="http://technorati.com/tags/ASP.NET" rel="tag">ASP.NET</a>,<a href="http://technorati.com/tags/MVC" rel="tag">MVC</a>,<a href="http://technorati.com/tags/Speaking" rel="tag">Speaking</a>,<a href="http://technorati.com/tags/Presentation" rel="tag">Presentation</a>,<a href="http://technorati.com/tags/Slides" rel="tag">Slides</a>,<a href="http://technorati.com/tags/Demo" rel="tag">Demo</a></div>
        <img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=15ae3174-d0bd-4639-9d9c-10d2feeaab35" />
      </body>
      <title>Presenting ASP.NET MVC 2: A (Microsoft) Web Coder's Salvation</title>
      <guid isPermaLink="false">http://www.cptloadtest.com/PermaLink,guid,15ae3174-d0bd-4639-9d9c-10d2feeaab35.aspx</guid>
      <link>http://www.cptloadtest.com/2010/05/23/Presenting-ASPNET-MVC-2-A-Microsoft-Web-Coders-Salvation.aspx</link>
      <pubDate>Sun, 23 May 2010 22:40:39 GMT</pubDate>
      <description>&lt;p&gt;
&amp;quot;There was a time when everything was moving towards the desktop. This Internet
thing was new and cool, but there was no way it would ever last. And no one knew how
to code for the web, at least not anything beyond animated lava lamps and cute &amp;quot;Under
Construction&amp;quot; images. So, to make coding for the web easier, they made ASP.NET
to be just like coding for a desktop, using the same patterns, the same event-based
model, and the same stateful approach. But the web isn't stateful, its only events
are GET and POST, and is nothing like a desktop, so we tortured ourselves for years
forcing a square peg through a round hole. The time has come for redemption, and its
name is ASP.NET MVC. Spend an hour discovering how coding for the web is supposed
to be--how it is today--and end your misery. Salvation awaits.&amp;quot;
&lt;/p&gt;
&lt;div style="text-align: center"&gt;
&lt;div style="margin: 0px auto; width: 425px" id="__ss_4091487"&gt;
&lt;object id="__sse4091487" width="425" height="355"&gt;
&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=asp-netmvc-awebcoderssalvationslideshare-100513220448-phpapp02&amp;amp;stripped_title=aspnet-mvc-2-a-microsoft-web-coders-salvation-4091487" /&gt;
&lt;param name="allowFullScreen" value="true" /&gt;
&lt;param name="allowScriptAccess" value="always" /&gt;&lt;embed name="__sse4091487" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=asp-netmvc-awebcoderssalvationslideshare-100513220448-phpapp02&amp;amp;stripped_title=aspnet-mvc-2-a-microsoft-web-coders-salvation-4091487" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;
&lt;/object&gt;
&lt;/div&gt;
&lt;a title="Slides for &amp;quot;ASP.NET MVC 2: A (Microsoft) Web Coder&amp;#39;s Salvation&amp;quot; on SlideShare" href="http://www.slideshare.net/jayharris/aspnet-mvc-2-a-microsoft-web-coders-salvation-4091487"&gt;Slides
on SlideShare&lt;/a&gt; | &lt;a title="Learn to Code ASP.NET MVC 2 : Introduction to ASP.NET MVC 2" href="http://www.cptloadtest.com/2010/02/23/Learn-To-Code-ASPNET-MVC-2-Introduction-To-ASPNET-MVC-2.aspx"&gt;Code
Walkthrough&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
At various user groups throughout Southeast Michigan and Northwest Ohio, I have been
presenting this topic since the last quarter of 2009. For those that are interested,
I have made the slide deck available on SlideShare. The code demo used during the
talk is available as a walkthrough via one of my installments of Learn to Code, where
you can create, step-by-step, the same ASP.NET MVC 2 application as was built during
the presentation.
&lt;/p&gt;
&lt;p&gt;
If you attend one of my presentations for this topic, I would appreciate your feedback.
If you are willing to tolerate a small registration process, SpeakerRate will allow
you to give feedback and anonymous ratings to the session you attended. If you are
interested in having me present this topic at your user group or conference, please
contact me.
&lt;/p&gt;
&lt;h3&gt;Past presentations on this topic: 
&lt;/h3&gt;
&lt;p&gt;
&lt;a title="Rate my ASP.NET MVC 2 Talk at AADND, May 2010" href="http://speakerrate.com/talks/3235-asp-net-mvc-2-a-microsoft-web-coder-s-salvation"&gt;Rate&lt;/a&gt; –
Ann Arbor .NET Developers, Ann Arbor, Michigan, May 2010 
&lt;br /&gt;
&lt;a title="Rate my ASP.NET MVC 2 Talk from GLUGnet Lansing, March 2010" href="http://speakerrate.com/talks/2865-asp-net-mvc-2-a-microsoft-web-coder-s-salvation"&gt;Rate&lt;/a&gt; –
GLUGnet, Lansing, Michigan, March 2010 
&lt;br /&gt;
&lt;a title="Rate my ASP.NET MVC 2 Talk at A2&amp;lt;DIV&amp;gt;, February 2010" href="http://speakerrate.com/talks/2175-asp-net-mvc-2-a-microsoft-web-coder-s-salvation"&gt;Rate&lt;/a&gt; –
A2&amp;lt;DIV&amp;gt;, Ann Arbor, Michigan, February 2010 
&lt;br /&gt;
&lt;a title="Rate my ASP.NET MVC 2 Talk at NWNUG, February 2010" href="http://speakerrate.com/talks/2134-asp-net-mvc-2-a-microsoft-web-coder-s-salvation"&gt;Rate&lt;/a&gt; –
NWNUG, Toledo, Ohio, February 2010 
&lt;br /&gt;
&lt;a title="Rate my ASP.NET MVC 2 Talk at GLUGnet Flint, February 2010" href="http://speakerrate.com/talks/3327-asp-net-mvc-2-a-microsoft-web-coder-s-salvation"&gt;Rate&lt;/a&gt; –
GLUGnet, Flint, Michigan, February 2010
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:97df05d2-ed4c-49b3-af36-91ee1db68b2a" class="wlWriterEditableSmartContent"&gt;Technorati
Tags: &lt;a href="http://technorati.com/tags/ASP.NET" rel="tag"&gt;ASP.NET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/MVC" rel="tag"&gt;MVC&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Speaking" rel="tag"&gt;Speaking&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Presentation" rel="tag"&gt;Presentation&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Slides" rel="tag"&gt;Slides&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Demo" rel="tag"&gt;Demo&lt;/a&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=15ae3174-d0bd-4639-9d9c-10d2feeaab35" /&gt;</description>
      <comments>http://www.cptloadtest.com/CommentView,guid,15ae3174-d0bd-4639-9d9c-10d2feeaab35.aspx</comments>
      <category>ASP.Net</category>
      <category>Events</category>
      <category>MVC</category>
      <category>Speaking</category>
    </item>
    <item>
      <trackback:ping>http://www.cptloadtest.com/Trackback.aspx?guid=4faf4135-777f-41e2-9239-dce95df5e2a7</trackback:ping>
      <pingback:server>http://www.cptloadtest.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.cptloadtest.com/PermaLink,guid,4faf4135-777f-41e2-9239-dce95df5e2a7.aspx</pingback:target>
      <dc:creator>Jay Harris</dc:creator>
      <wfw:comment>http://www.cptloadtest.com/CommentView,guid,4faf4135-777f-41e2-9239-dce95df5e2a7.aspx</wfw:comment>
      <wfw:commentRss>http://www.cptloadtest.com/SyndicationService.asmx/GetEntryCommentsRss?guid=4faf4135-777f-41e2-9239-dce95df5e2a7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In ASP.NET MVC, the default signature for a Details action includes an Int32 method
argument. The system works fine when the expected data is entered, and the happy path
is followed, but put in an invalid value or no value at all, and an exception explodes
all over the user.
</p>
        <blockquote>
          <p style="color: maroon">
            <em>The parameters dictionary contains a null entry for parameter 'id' of non-nullable
type 'System.Int32' for method 'System.Web.Mvc.ActionResult Details(Int32)' in 'MvcSampleApplication.Controllers.WidgetController'.</em>
          </p>
        </blockquote>
        <p>
The following solution applies to the ASP.NET MVC 2 framework. If you are looking
for a solution in the first version of the ASP.NET MVC framework, try last November's
post on <a href="http://www.cptloadtest.com/2009/12/01/Validating-ASPNET-MVC-Route-Values-With-ActionFilterAttribute.aspx">Validating
ASP.NET MVC Route Values with ActionFilterAttribute</a>.
</p>
        <p>
By default, the third section of an ASP.NET MVC Route is the Id, passed as a method
argument to a controller action. This value is an optional URL Parameter (UrlParameter.Optional),
as defined in the default routing tables, but the value can be parsed to other types
such as an integer for a default Details action. The problem stems from when invalid
values or missing values are passed to these integer-expecting actions; MVC handles
the inability to parse the value into an integer, but then throws an exception trying
to pass a null value to a Controller Action expecting a value type for a method argument.
</p>
        <p>
A common solution is to convert the method argument to a nullable integer, which will
automatically cause the argument to be null when the route value specified in the
URL is an empty or non-integer value. The solution works fine, but seems a little
lame to me; I want to avoid having to check HasValue within every action. I have to
check for invalid identity values anyway (a user with an id of –1 isn’t going to exist
in my system), so I would much rather default these invalid integers to one of these
known, invalid values.
</p>
        <p>
Under ASP.NET MVC 2, the solution lies with a DefaultValueAttribute. Prior to executing
a Controller Action, the DefaultValueAttribute can validate that the specified route
value meets an expected type, and correct the value to a default value if this validation
fails; this allows me to keep that method argument as a value-type integer and avoid
Nullable&lt;int&gt;.HasValue.
</p>
        <p>
The attribute is a member of the System.ComponentModel namespace, and accepts any
one of many different base values as the default to assign to the route value should
the parsing fail. Unlike the ActionFilterAttribute used to solve this problem in the
first version of the ASP.NET MVC framework, there are no route redirects, which also
means we do not modify the browser URL. (Using the ActionFilterAttribute, the browser
location is redirected from ~/Widgets/Details/ or ~/Widgets/Details/Foo to ~/Widgets/Details/0,
but with the DefaultValueAttribute, no such redirect occurs.)
</p>
        <h3>Usage
</h3>
        <pre class="csharp:nocontrols" name="code">public class WidgetsController : Controller
{
  public ActionResult Details([DefaultValue(0) int id)
  {
    return View();
  }
}</pre>
        <p>
There is very little code to make this all happen. With one attribute added to the
method argument, MVC validates that my identity is an integer or otherwise provides
a replacement default value. I can depend on my user input without having to laden
my code with unnecessary value checks and without risk of unhandled exceptions. However,
the DefaultValueAttribute is just for providing a default value for your value-type
method arguments. Unlike the ActionFilterAttribute, the DefaultValueAttribute will
not perform any filtering, such as making sure a string argument begins with "Foo"
or that a decimal input only contains two decimal places; for this type of logic,
continue to use the ActionFilterAttribute. DefaultValueAttribute is a perfect fit
for eliminating Nullable&lt;int&gt; in Action arguments, making the code clean, simple,
and elegant. Eliminate the extra code, and let the framework do the work for you.
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a0a44014-ffba-4b02-b952-0ae0181262d7" class="wlWriterEditableSmartContent">Technorati
Tags: <a href="http://technorati.com/tags/ASP.NET" rel="tag">ASP.NET</a>,<a href="http://technorati.com/tags/MVC" rel="tag">MVC</a>,<a href="http://technorati.com/tags/DefaultFilterAttribute" rel="tag">DefaultFilterAttribute</a></div>
        <img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=4faf4135-777f-41e2-9239-dce95df5e2a7" />
      </body>
      <title>Validating ASP.NET MVC 2 Route Values with DefaultValueAttribute</title>
      <guid isPermaLink="false">http://www.cptloadtest.com/PermaLink,guid,4faf4135-777f-41e2-9239-dce95df5e2a7.aspx</guid>
      <link>http://www.cptloadtest.com/2010/04/05/Validating-ASPNET-MVC-2-Route-Values-With-DefaultValueAttribute.aspx</link>
      <pubDate>Mon, 05 Apr 2010 02:08:03 GMT</pubDate>
      <description>&lt;p&gt;
In ASP.NET MVC, the default signature for a Details action includes an Int32 method
argument. The system works fine when the expected data is entered, and the happy path
is followed, but put in an invalid value or no value at all, and an exception explodes
all over the user.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p style="color: maroon"&gt;
&lt;em&gt;The parameters dictionary contains a null entry for parameter 'id' of non-nullable
type 'System.Int32' for method 'System.Web.Mvc.ActionResult Details(Int32)' in 'MvcSampleApplication.Controllers.WidgetController'.&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The following solution applies to the ASP.NET MVC 2 framework. If you are looking
for a solution in the first version of the ASP.NET MVC framework, try last November's
post on &lt;a href="http://www.cptloadtest.com/2009/12/01/Validating-ASPNET-MVC-Route-Values-With-ActionFilterAttribute.aspx"&gt;Validating
ASP.NET MVC Route Values with ActionFilterAttribute&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
By default, the third section of an ASP.NET MVC Route is the Id, passed as a method
argument to a controller action. This value is an optional URL Parameter (UrlParameter.Optional),
as defined in the default routing tables, but the value can be parsed to other types
such as an integer for a default Details action. The problem stems from when invalid
values or missing values are passed to these integer-expecting actions; MVC handles
the inability to parse the value into an integer, but then throws an exception trying
to pass a null value to a Controller Action expecting a value type for a method argument.
&lt;/p&gt;
&lt;p&gt;
A common solution is to convert the method argument to a nullable integer, which will
automatically cause the argument to be null when the route value specified in the
URL is an empty or non-integer value. The solution works fine, but seems a little
lame to me; I want to avoid having to check HasValue within every action. I have to
check for invalid identity values anyway (a user with an id of –1 isn’t going to exist
in my system), so I would much rather default these invalid integers to one of these
known, invalid values.
&lt;/p&gt;
&lt;p&gt;
Under ASP.NET MVC 2, the solution lies with a DefaultValueAttribute. Prior to executing
a Controller Action, the DefaultValueAttribute can validate that the specified route
value meets an expected type, and correct the value to a default value if this validation
fails; this allows me to keep that method argument as a value-type integer and avoid
Nullable&amp;lt;int&amp;gt;.HasValue.
&lt;/p&gt;
&lt;p&gt;
The attribute is a member of the System.ComponentModel namespace, and accepts any
one of many different base values as the default to assign to the route value should
the parsing fail. Unlike the ActionFilterAttribute used to solve this problem in the
first version of the ASP.NET MVC framework, there are no route redirects, which also
means we do not modify the browser URL. (Using the ActionFilterAttribute, the browser
location is redirected from ~/Widgets/Details/ or ~/Widgets/Details/Foo to ~/Widgets/Details/0,
but with the DefaultValueAttribute, no such redirect occurs.)
&lt;/p&gt;
&lt;h3&gt;Usage
&lt;/h3&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;public class WidgetsController : Controller
{
  public ActionResult Details([DefaultValue(0) int id)
  {
    return View();
  }
}&lt;/pre&gt;
&lt;p&gt;
There is very little code to make this all happen. With one attribute added to the
method argument, MVC validates that my identity is an integer or otherwise provides
a replacement default value. I can depend on my user input without having to laden
my code with unnecessary value checks and without risk of unhandled exceptions. However,
the DefaultValueAttribute is just for providing a default value for your value-type
method arguments. Unlike the ActionFilterAttribute, the DefaultValueAttribute will
not perform any filtering, such as making sure a string argument begins with &amp;quot;Foo&amp;quot;
or that a decimal input only contains two decimal places; for this type of logic,
continue to use the ActionFilterAttribute. DefaultValueAttribute is a perfect fit
for eliminating Nullable&amp;lt;int&amp;gt; in Action arguments, making the code clean, simple,
and elegant. Eliminate the extra code, and let the framework do the work for you.
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a0a44014-ffba-4b02-b952-0ae0181262d7" class="wlWriterEditableSmartContent"&gt;Technorati
Tags: &lt;a href="http://technorati.com/tags/ASP.NET" rel="tag"&gt;ASP.NET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/MVC" rel="tag"&gt;MVC&lt;/a&gt;,&lt;a href="http://technorati.com/tags/DefaultFilterAttribute" rel="tag"&gt;DefaultFilterAttribute&lt;/a&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=4faf4135-777f-41e2-9239-dce95df5e2a7" /&gt;</description>
      <comments>http://www.cptloadtest.com/CommentView,guid,4faf4135-777f-41e2-9239-dce95df5e2a7.aspx</comments>
      <category>ASP.Net</category>
      <category>MVC</category>
    </item>
    <item>
      <trackback:ping>http://www.cptloadtest.com/Trackback.aspx?guid=1d5d9618-a51a-471f-a5ec-7381c916f11d</trackback:ping>
      <pingback:server>http://www.cptloadtest.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.cptloadtest.com/PermaLink,guid,1d5d9618-a51a-471f-a5ec-7381c916f11d.aspx</pingback:target>
      <dc:creator>Jay Harris</dc:creator>
      <wfw:comment>http://www.cptloadtest.com/CommentView,guid,1d5d9618-a51a-471f-a5ec-7381c916f11d.aspx</wfw:comment>
      <wfw:commentRss>http://www.cptloadtest.com/SyndicationService.asmx/GetEntryCommentsRss?guid=1d5d9618-a51a-471f-a5ec-7381c916f11d</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
On Tuesday, February 9th, I was scheduled lead a jam session for Come Jam With Us,
the software developer study group in Ann Arbor. The session was to be on ASP.NET
MVC 2, aimed to give attendees enough of an introduction to the product to empower
developers to be able to start coding their own ASP.NET MVC 2 projects. Unfortunately,
Mother Nature did not cooperate that day, half of the state of Michigan seemingly
shut down under 8" of snow, and the session was cancelled and rescheduled for
February 23rd. The goal of these Learn to Code exercises is to give you an introduction
to building applications with ASP.NET MVC 2. In the near future, I also hope to provide
a screen cast of these same exercises.
</p>
        <h3>About this Exercise
</h3>
        <p>
This coding exercise is designed to give you an introduction to ASP.NET MVC 2. In
this exercise, developers will create their first database-driven ASP.NET MVC 2 application
within Visual Studio, primarily using code generation built in to Visual Studio. Developers
performing this exercise should be familiar with ASP.NET development and Visual Studio,
but no previous experience with ASP.NET MVC is required.
</p>
        <h3>Prerequisites
</h3>
        <p>
You will need few things for ASP.NET MVC 2 application development and to complete
these exercises. Please complete the following prerequisites prior to moving on. The
session is designed to be completed in about an hour, but prerequisite setup is not
included in that time.
</p>
        <ul>
          <li>
Install <a href="http://www.microsoft.com/visualstudio/">Microsoft Visual Studio 2008
SP1</a> or <a href="http://www.microsoft.com/express/Web/">Visual Web Developer 2008
Express</a> with SP1 
</li>
          <li>
Install <a href="http://www.microsoft.com/sqlserver/2008/">Microsoft SQL Server</a> or <a href="http://www.microsoft.com/express/Database/">SQL
Server Express</a></li>
          <li>
Download and install the latest <a title="ASP.NET MVC 2 RC 2 on Microsoft" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=7aba081a-19b9-44c4-a247-3882c8f749e3&amp;displaylang=en">ASP.NET
MVC 2 RC 2 bits from Microsoft</a></li>
        </ul>
        <h3>Exercise 0: Getting Started
</h3>
        <h4>Creating a Project
</h4>
        <p>
Before any coding can occur, the first thing that we have to do is create a new ASP.NET
MVC 2 project from within Visual Studio.
</p>
        <ol>
          <li>
In Visual Studio, create a new "ASP.NET MVC 2 Web Application" named MvcJamSession.
You can create your project in either Visual Basic or Visual C#, though all of the
examples in this post will be in C#. 
</li>
          <li>
After selecting the project type and solution/project name, you will be prompted for
creating a unit test project. Select "Yes." Though we will not be using
these tests in this exercise, we will be in future installments. 
</li>
          <li>
Be sure that your MvcJamSession.Test project includes a project reference back to
your MvcJamSession project. 
</li>
          <li>
Compile and run. Your browser should display a blue web site showing "Welcome
to ASP.NET MVC!" Congratulations. You now have your first ASP.NET MVC application. 
</li>
        </ol>
        <h4>Convention-Based Development
</h4>
        <p>
          <a href="http://www.cptloadtest.com/content/binary/WindowsLiveWriter/ASP.NETMVCJamSession_14C62/SolutionExplorer-MvcJamSession.jpg">
            <img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Project Folder Structure of MVC Jam Session Project" border="0" alt="Project Folder Structure of MVC Jam Session Project" align="right" src="http://www.cptloadtest.com/content/binary/WindowsLiveWriter/ASP.NETMVCJamSession_14C62/SolutionExplorer-MvcJamSession_thumb.jpg" width="200" height="382" />
          </a> Development
within ASP.NET MVC is based on convention over configuration. Certain naming conventions
are built in the system to eliminate the amount of boiler-plate code that you need
to recreate. That is not to say that you <em>must</em> follow these naming conventions—you
may use whatever convention you like—but by straying from the standardized conventions,
you will be creating a lot of extra work for yourself. With our new ASP.NET MVC 2
Project, a few of these conventions are immediately visible.
</p>
        <ul>
          <li>
            <em>Controllers</em> folder. This is where all Controller classes must go. Individual
classes must be named <em>&lt;Name&gt;Controller</em>. The default project includes <em>HomeController</em>,
which governs the Home and About actions, and <em>AccountController</em>, which governs
the log in, log out, change password, and registration actions. If we were to make
an application that manages Widgets, we would likely have a class named <em>WidgetController</em>. 
</li>
          <li>
            <em>Views</em> folder. This is where all of the Views must go. By default, views are
paired one-to-one with controller actions, such as one view for new user registration
and another view for changing your password. Views are also separated into folders
matching the associated controller name—<em>/Views/&lt;ControllerName&gt;/&lt;ActionName&gt;</em>.
Thus, <em>HomeController</em>'s About action is associated with the <em>/Views/Home/About</em> view. 
<br />
The Views folder also contains a <em>Shared</em> folder. This folder is where any
common views, such as a Master Page, would reside. The <em>Shared</em> folder is also
where the ViewEngine cascades to when it can't find an appropriate view in the /<em>Views/&lt;ControllerName&gt;</em> folder;
if <em>/Views/Home/About</em> didn't exist, the ViewEngine would look for <em>/Views/Shared/About</em>.
This can come in handy for common pages shared by all controllers, such as an error
page. 
</li>
        </ul>
        <h3>Session Exercise 1: Building an Application
</h3>
        <p>
Using the project we just created, we're going to create an application that manage
a list of employees, including their name, job title, date of hire, and date of termination.
Though the default project is a great help on some applications, it can get in the
way on others; we're not going to need any account services in our application, so
we need to first trim the project down a little.
</p>
        <ol>
          <li>
Delete the entire <em>Account</em> folder under /Views/. 
</li>
          <li>
Delete <em>AccountController.cs</em> from the Controllers folder. 
</li>
          <li>
Delete shared partial view <em>/Views/Shared/LogOnUserControl.ascx</em>. 
</li>
          <li>
Delete reference to this partial view by removing the "LoginDisplay" DIV
from<em> /Views/Shared/Site.Master</em>, lines 18-20. 
</li>
          <li>
Removing <em>LoginDisplay</em> will cause a slight layout problem from the CSS. To
fix it, modify the <em>#menucontainer</em> definition in <em>/Content/Site.css</em> on
line 263. 
<br /><pre class="css:nocontrols" name="code">#menucontainer
{
    padding-top:40px;
}</pre></li>
          <li>
Save all, compile, and Run. The site should be functioning normally, but without the
Log In link in the top right of the home page. 
</li>
        </ol>
        <h4>Creating a Database
</h4>
        <p>
Like any dynamic web site, we need a storage mechanism. Create a database in SQL Server
or SQL Server Express with an Employee table containing columns for name, job title,
hired date, and termination date, as well as an identity column for finding records.<a href="http://www.cptloadtest.com/content/binary/WindowsLiveWriter/ASP.NETMVCJamSession_14C62/MvcJamSession-EmployeeTable_1.jpg"><img style="border-right-width: 0px; margin: 5px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="MvcJamSession-EmployeeTable" border="0" alt="MvcJamSession-EmployeeTable" align="right" src="http://www.cptloadtest.com/content/binary/WindowsLiveWriter/ASP.NETMVCJamSession_14C62/MvcJamSession-EmployeeTable_thumb_1.jpg" width="250" height="283" /></a></p>
        <ul>
          <li>
For those with SQL Server Express, create a new database through right-clicking the
App_Data folder, and adding a new item. The new item should be a SQL Server Database. 
</li>
          <li>
For those with SQL Server, create a new database through SQL Server Management Studio
(SSMS). 
</li>
        </ul>
        <ol>
          <li>
Create a new table called <em>Employee</em>. 
</li>
          <li>
Create the following columns within the new table: 
<ul><li>
Id (primary key, identity, int, not null) 
</li><li>
Name (varchar(50), not null) 
</li><li>
JobTitle (varchar(50), not null) 
</li><li>
HiredOn (date, not null) 
</li><li>
TerminatedOn (date, null) 
</li></ul></li>
          <li>
Add a record or two to the table for good measure. 
</li>
        </ol>
        <h4>Creating a Model
</h4>
        <p>
The next thing we need to create is our Model. Not only is it the code representation
for our business entity (An Employee class contains Name, JobTitle, HiredOn, and TerminatedOn
properties), it is also responsible for <em>how</em> to get, save, or delete data
from the database. We will be using Microsoft Entity Framework through Visual Studio
to generate our model for us.
</p>
        <ol>
          <li>
To create our new Model, right-click the <em>Model</em> folder and select Add New
Item. The new item should be an ADO.NET Entity Data Model, found within the Data category
of the Add New Item dialog. Name it MvcJamSessionEntities. 
</li>
          <li>
Generate the Model from a database, connecting to your MVC Jam Session database created
in the previous section. On the step where you select your database connection, be
sure to allow Visual Studio to add the connection string to your web.config by checking
the appropriate checkbox. 
</li>
          <li>
The <em>Employee</em> table is the only Data Object that needs to be generated. 
</li>
          <li>
When the dialog completes, your Entity Data Model (a .edmx file) should be displayed
in design view. 
</li>
          <li>
Save all and compile. 
</li>
        </ol>
        <h4>Creating a Controller
</h4>
        <p>
Now that our model is in place, we need to create a controller. The controller is
responsible for managing all interaction between the end-user and the application,
including identifying what data to get, save, or delete. (Remember, though the Controller
is responsible for <em>what</em>, the Model is responsible for <em>how</em>.)
</p>
        <ol>
          <li>
To create our new Controller, right-click the <em>Controller</em> folder and select
Add Controller. Since the name matters in ASP.NET MVC's convention-over-configuration
style, name it EmployeeController.cs (or .vb, if you happen to be working in Visual
Basic .NET). Be sure to check the "Add action methods for Create, Update, Detail,
and Delete scenarios" as we will be using them later. 
</li>
          <li>
We now have a basic controller, but it doesn't do anything yet. First, we want to
modify our Index action, as it is the default action in the controller. We will use
this action to list all of the Employees that currently exist in our database. Your
Index() action method should contain the following code: 
<br /><pre class="csharp:nocontrols" name="code">var _entities = new MvcJamSession.Models.MvcJamSessionEntities();
return View(_entities.Employee.ToList());</pre></li>
          <li>
Save all and compile. 
</li>
        </ol>
        <h4>Creating a View
</h4>
        <p>
We have our Model and we have our Controller, so it is time for our View. The View
is responsible for display only—it should contain virtually no logic. Our controller
doesn't do anything yet, but we can at least get the base file structure and navigation
in place. Since our Model governs <em>how</em> and our Controller governs <em>what</em>,
think of the View as governing <em>where</em>, as it is responsible for deciding where
each data element gets displayed on your page.
</p>
        <ol>
          <li>
Once you have saved and compiled your Controller, right-click on the Index action
name and select Add View. 
</li>
          <li>
The View should be named Index, just like your Controller action. Also, make your
View strongly typed to the Employee model. Since a list of Employees is being passed
to the View from the Controller, making the View strongly-typed prevents us from having
to cast our View Model from object to Employee. Finally, since we are providing a
list of Employees, the View Content should be a List. 
</li>
          <li>
The <em>Employee</em> folder should be automatically created under the <em>/Views/</em> folder,
and the <em>Index.aspx</em> View inside of this new <em>Employee</em> folder. 
</li>
          <li>
The last thing we need to do is provide some navigation to this view. Open up <em>/Views/Shared/Site.Master</em> and
add an ActionLink within the Menu Container section to the Index action of the Employee
controller. When you are done, the Menu Container should look like this: 
<br /><pre class="csharp:nocontrols" name="code">&lt;ul id="menu"&gt;              
  &lt;li&gt;&lt;%= Html.ActionLink("Home", "Index", "Home")%&gt;&lt;/li&gt;
  &lt;li&gt;&lt;%= Html.ActionLink("About", "About", "Home")%&gt;&lt;/li&gt;
  &lt;li&gt;&lt;%= Html.ActionLink("Employees", "Index", "Employee")%&gt;&lt;/li&gt;
&lt;/ul&gt;</pre></li>
          <li>
Save all and run. When you navigate to your Employees link, you should get a list
of all employees currently in the database with an Edit, Details, and Delete links. 
</li>
        </ol>
        <blockquote>
          <h5>New in ASP.NET MVC 2: Strongly Typed HTML Helpers
</h5>
          <p>
In the previous version of ASP.NET MVC, HTML helpers were simple generic classes.
Generated views were full of Magic Strings for each property in your model, such as
&lt;%= Html.TextBox("Name") %&gt;, opening the door for a fat-fingered property
name. MVC 2 includes strongly-typed HTML helpers on strongly-typed views. For form-based
views, use the new strongly-typed "For" methods, such as &lt;%= Html.TextBoxFor(model
=&gt; model.Name) %&gt; or &lt;%= Html.EditorFor(model =&gt; model.Name) %&gt; to
eliminate the risk of incorrectly entering a property name. For display fields, use
Html.DisplayFor() to provide similar benefits for your read-only data, including the
elimination of HTML encoding for each field.
</p>
        </blockquote>
        <h4>Adding New Data
</h4>
        <p>
A list of employees is great, but we also need the ability to manipulate that data.
First, let's start with the ability to create new data.
</p>
        <ol>
          <li>
Within Visual Studio, open <em>/Controllers/EmployeeController</em> and navigate to
the POST Create action. POST is an HTTP verb associated with pushing data to the server
in the HTTP header, commonly associated with form submits. GET is the HTTP verb for
pure retrieval, commonly associated with a direct URL request, such as clicking a
link. In this case, the POST action can be identified by the [HttpPost] decoration. 
</li>
          <li>
The method arguments currently include only a FormCollection object that will contain
all of the header values associated with the POST. However, MVC is smart; it can automatically
transform this collection into a type-safe Model, based on the names of the header
variables (the identities of the HTML form inputs match the names of the Model's properties).
The one exception is the Id attribute, which is available in the Model but not populated
until after the object is saved to the database. To get strong typing, and avoid having
to manually cast or map form collection data to a new instance of our Model, change
the method signature to the following: 
<br /><pre class="csharp:nocontrols" name="code">public ActionResult Create([Bind(Exclude="Id")] Employee newEmployee)</pre></li>
          <li>
Now that we have a populated Model, we just need to save the Model to the database
and redirect back to the List when we are done. Do this by replacing the contents
of the action method with the following code: 
<br /><pre class="csharp:nocontrols" name="code">try
{
  if (!ModelState.IsValid) return View();

  var _entities = new MvcJamSession.Models.MvcJamSessionEntities();
  _entities.AddToEmployee(employee);
  _entities.SaveChanges();
  return RedirectToAction("Index");
}
catch
{
  return View();
}</pre></li>
          <li>
Save and compile. 
</li>
          <li>
Now we must create the View for adding data. As we did with Index, we can create the
view by right-clicking the Action method and selecting Add View. The view content
should be Create. 
</li>
          <li>
The only modification for the Create view is the Id property. The generated code creates
an input for this property, but it is not needed since the column value is auto-populated
by the database when saving the entity. Remove this input and label from the form. 
</li>
          <li>
Save and run. You should now be able to add new records to the database. 
</li>
        </ol>
        <blockquote>
          <h5>New in ASP.NET MVC2: Better Verb Attributes
</h5>
          <p>
In the first version of ASP.NET MVC, HTTP Verb conditions were placed on an Action
via the AcceptVerbsAttribute, such as the Create action's [AcceptVerbs(HttpVerbs.Post)].
In ASP.NET MVC 2, these attributes have been simplified with the introduction of the
HttpGetAttribute, HttpDeleteAttribute, HttpPostAttribute, and HttpPutAttribute.
</p>
        </blockquote>
        <h4>Routing and Updates
</h4>
        <p>
The end user can view a list of Employees, and can create new employees, but when
the end user clicks the Edit or Detail links, they get an error since these Views
haven't been created yet and the Actions are not implemented. One by one, we will
get the new views in place.
</p>
        <ol>
          <li>
Within Visual Studio, open <em>/Controllers/EmployeeController</em> and navigate to
the Details action. You may notice that the method already accepts an integer as input,
and shows example usage of the action in a commented URL above the method: <em>/Employee/Details/5</em>.
This integer is the identity value of the Employee record, and is already populated
in the links of our List view created in the previous section. 
</li>
          <li>
Within Visual Studio, open <em>Global.asax</em> and navigate to the RegisterRoutes
method. The default route for ASP.NET MVC is <em>/{controller}/{action}/{id}/</em>.
By parsing out any URL into the application, MVC can determine which Controller to
use, which Action to execute, and which arguments to pass to the Action. Later portions
of the URL path are often optional, and when not specified, are replaced with the
default values: Home, Index, and String.Empty. The URLs of "/", "/Home",
"/Home/", "/Home/Index", and "/Home/Index/" are all
equivalent URLs in the eyes of ASP.NET MVC. 
</li>
        </ol>
        <p>
Go back to the Employee controller. Now that we know what the integer argument is
for, we need to retrieve the Employee matching the associated identity and pass it
to a view for editing or display.
</p>
        <ol>
          <li>
Replace the contents of the GET version of the Edit action method with the following
code to retrieve the Employee from the database that matches the identity specified
in the route: 
<br /><pre class="csharp:nocontrols" name="code">var _entities = new MvcJamSession.Models.MvcJamSessionEntities();
return View(_entities.Employee.Where(emp =&gt; emp.Id == id).First());</pre></li>
          <li>
Save and compile. 
</li>
          <li>
Right-click the Action and add the View. The View should still be strongly typed,
but this time the view content should be Edit. 
</li>
          <li>
The Details and GET Delete actions are largely similar as the GET Edit action, except
that the view is labels instead of text boxes. Repeat the above three steps for the
Details action method with a Details view content and for the GET Delete action method
with a Delete view content. 
</li>
          <li>
As with the Create view, the Id property should be removed from the Edit view, as
it is not an item that should be edited by the end user. 
</li>
          <li>
Save and run. You should see the details of an Employee when clicking on the Edit
and Details links. 
</li>
          <li>
We can view Employee details within the Edit form, but when we make changes and submit,
nothing happens. We need to modify the POST Edit action to save our changes back to
the database. The default POST Edit action accepts an id and a FormCollection as input
arguments, but similarly to the POST Create action, we can change this to use our
strongly typed model to avoid having to cast or map data. However, unlike our Create
action, we need to bind the id property so that the system knows which record to update.
To make these modifications, replace the POST Edit signature with the following: 
<br /><pre class="csharp:nocontrols" name="code">public ActionResult Edit(MvcJamSession.Models.Employee employee)</pre></li>
          <li>
Replace the contents of the POST Edit action method with the following code to save
the changes to the database: 
<br /><pre class="csharp:nocontrols" name="code">try
{
  if (!ModelState.IsValid) return View();

  var _entities = new MvcJamSession.Models.MvcJamSessionEntities();
  var _originalEmployee =
    _entities.Employee.Where(emp =&gt; emp.Id == employee.Id).First();
  _entities.ApplyPropertyChanges(_originalEmployee.EntityKey.EntitySetName,
                                 employee);
  _entities.SaveChanges();
  return RedirectToAction("Index");
}
catch
{
  return View();
}</pre></li>
          <li>
Replace the signature of the POST Delete action method with the following code to
provide strong typing on our model: 
<br /><pre class="csharp:nocontrols" name="code">public ActionResult Delete(MvcJamSession.Models.Employee employee)</pre></li>
          <li>
Finally, replace the contents of the POST Delete action method with the following
code to delete a record: 
<br /><pre class="csharp:nocontrols" name="code">var _entites = new MvcJamSession.Models.MvcJamSessionEntities();
var originalEmployee =
  _entites.Employee.Where(emp =&gt; emp.Id == deletedEmployee.Id).First();
_entites.DeleteObject(originalEmployee);
_entites.SaveChanges();
return RedirectToAction("Index");</pre></li>
          <li>
Save, compile, and run. You should now be able to modify existing Employee records. 
</li>
        </ol>
        <p>
We now have a fully-functional ASP.NET MVC application to manage our Employee records.
Congratulations!
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:13d5b303-4a7f-4ac9-93a3-f208ffe24fe0" class="wlWriterEditableSmartContent">Technorati
Tags: <a href="http://technorati.com/tags/ASP.NET+MVC" rel="tag">ASP.NET MVC</a>,<a href="http://technorati.com/tags/MVC" rel="tag">MVC</a>,<a href="http://technorati.com/tags/Jam+Session" rel="tag">Jam
Session</a>,<a href="http://technorati.com/tags/Coding+Exercise" rel="tag">Coding
Exercise</a>,<a href="http://technorati.com/tags/Learn+to+Code" rel="tag">Learn to
Code</a></div>
        <img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=1d5d9618-a51a-471f-a5ec-7381c916f11d" />
      </body>
      <title>Learn to Code ASP.NET MVC 2 : Introduction to ASP.NET MVC 2</title>
      <guid isPermaLink="false">http://www.cptloadtest.com/PermaLink,guid,1d5d9618-a51a-471f-a5ec-7381c916f11d.aspx</guid>
      <link>http://www.cptloadtest.com/2010/02/23/Learn-To-Code-ASPNET-MVC-2-Introduction-To-ASPNET-MVC-2.aspx</link>
      <pubDate>Tue, 23 Feb 2010 22:38:00 GMT</pubDate>
      <description>&lt;p&gt;
On Tuesday, February 9th, I was scheduled lead a jam session for Come Jam With Us,
the software developer study group in Ann Arbor. The session was to be on ASP.NET
MVC 2, aimed to give attendees enough of an introduction to the product to empower
developers to be able to start coding their own ASP.NET MVC 2 projects. Unfortunately,
Mother Nature did not cooperate that day, half of the state of Michigan seemingly
shut down under 8&amp;quot; of snow, and the session was cancelled and rescheduled for
February 23rd. The goal of these Learn to Code exercises is to give you an introduction
to building applications with ASP.NET MVC 2. In the near future, I also hope to provide
a screen cast of these same exercises.
&lt;/p&gt;
&lt;h3&gt;About this Exercise
&lt;/h3&gt;
&lt;p&gt;
This coding exercise is designed to give you an introduction to ASP.NET MVC 2. In
this exercise, developers will create their first database-driven ASP.NET MVC 2 application
within Visual Studio, primarily using code generation built in to Visual Studio. Developers
performing this exercise should be familiar with ASP.NET development and Visual Studio,
but no previous experience with ASP.NET MVC is required.
&lt;/p&gt;
&lt;h3&gt;Prerequisites
&lt;/h3&gt;
&lt;p&gt;
You will need few things for ASP.NET MVC 2 application development and to complete
these exercises. Please complete the following prerequisites prior to moving on. The
session is designed to be completed in about an hour, but prerequisite setup is not
included in that time.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Install &lt;a href="http://www.microsoft.com/visualstudio/"&gt;Microsoft Visual Studio 2008
SP1&lt;/a&gt; or &lt;a href="http://www.microsoft.com/express/Web/"&gt;Visual Web Developer 2008
Express&lt;/a&gt; with SP1 
&lt;/li&gt;
&lt;li&gt;
Install &lt;a href="http://www.microsoft.com/sqlserver/2008/"&gt;Microsoft SQL Server&lt;/a&gt; or &lt;a href="http://www.microsoft.com/express/Database/"&gt;SQL
Server Express&lt;/a&gt; 
&lt;/li&gt;
&lt;li&gt;
Download and install the latest &lt;a title="ASP.NET MVC 2 RC 2 on Microsoft" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=7aba081a-19b9-44c4-a247-3882c8f749e3&amp;amp;displaylang=en"&gt;ASP.NET
MVC 2 RC 2 bits from Microsoft&lt;/a&gt; 
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Exercise 0: Getting Started
&lt;/h3&gt;
&lt;h4&gt;Creating a Project
&lt;/h4&gt;
&lt;p&gt;
Before any coding can occur, the first thing that we have to do is create a new ASP.NET
MVC 2 project from within Visual Studio.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
In Visual Studio, create a new &amp;quot;ASP.NET MVC 2 Web Application&amp;quot; named MvcJamSession.
You can create your project in either Visual Basic or Visual C#, though all of the
examples in this post will be in C#. 
&lt;/li&gt;
&lt;li&gt;
After selecting the project type and solution/project name, you will be prompted for
creating a unit test project. Select &amp;quot;Yes.&amp;quot; Though we will not be using
these tests in this exercise, we will be in future installments. 
&lt;/li&gt;
&lt;li&gt;
Be sure that your MvcJamSession.Test project includes a project reference back to
your MvcJamSession project. 
&lt;/li&gt;
&lt;li&gt;
Compile and run. Your browser should display a blue web site showing &amp;quot;Welcome
to ASP.NET MVC!&amp;quot; Congratulations. You now have your first ASP.NET MVC application. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Convention-Based Development
&lt;/h4&gt;
&lt;p&gt;
&lt;a href="http://www.cptloadtest.com/content/binary/WindowsLiveWriter/ASP.NETMVCJamSession_14C62/SolutionExplorer-MvcJamSession.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Project Folder Structure of MVC Jam Session Project" border="0" alt="Project Folder Structure of MVC Jam Session Project" align="right" src="http://www.cptloadtest.com/content/binary/WindowsLiveWriter/ASP.NETMVCJamSession_14C62/SolutionExplorer-MvcJamSession_thumb.jpg" width="200" height="382" /&gt;&lt;/a&gt; Development
within ASP.NET MVC is based on convention over configuration. Certain naming conventions
are built in the system to eliminate the amount of boiler-plate code that you need
to recreate. That is not to say that you &lt;em&gt;must&lt;/em&gt; follow these naming conventions—you
may use whatever convention you like—but by straying from the standardized conventions,
you will be creating a lot of extra work for yourself. With our new ASP.NET MVC 2
Project, a few of these conventions are immediately visible.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Controllers&lt;/em&gt; folder. This is where all Controller classes must go. Individual
classes must be named &lt;em&gt;&amp;lt;Name&amp;gt;Controller&lt;/em&gt;. The default project includes &lt;em&gt;HomeController&lt;/em&gt;,
which governs the Home and About actions, and &lt;em&gt;AccountController&lt;/em&gt;, which governs
the log in, log out, change password, and registration actions. If we were to make
an application that manages Widgets, we would likely have a class named &lt;em&gt;WidgetController&lt;/em&gt;. 
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Views&lt;/em&gt; folder. This is where all of the Views must go. By default, views are
paired one-to-one with controller actions, such as one view for new user registration
and another view for changing your password. Views are also separated into folders
matching the associated controller name—&lt;em&gt;/Views/&amp;lt;ControllerName&amp;gt;/&amp;lt;ActionName&amp;gt;&lt;/em&gt;.
Thus, &lt;em&gt;HomeController&lt;/em&gt;'s About action is associated with the &lt;em&gt;/Views/Home/About&lt;/em&gt; view. 
&lt;br /&gt;
The Views folder also contains a &lt;em&gt;Shared&lt;/em&gt; folder. This folder is where any
common views, such as a Master Page, would reside. The &lt;em&gt;Shared&lt;/em&gt; folder is also
where the ViewEngine cascades to when it can't find an appropriate view in the /&lt;em&gt;Views/&amp;lt;ControllerName&amp;gt;&lt;/em&gt; folder;
if &lt;em&gt;/Views/Home/About&lt;/em&gt; didn't exist, the ViewEngine would look for &lt;em&gt;/Views/Shared/About&lt;/em&gt;.
This can come in handy for common pages shared by all controllers, such as an error
page. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Session Exercise 1: Building an Application
&lt;/h3&gt;
&lt;p&gt;
Using the project we just created, we're going to create an application that manage
a list of employees, including their name, job title, date of hire, and date of termination.
Though the default project is a great help on some applications, it can get in the
way on others; we're not going to need any account services in our application, so
we need to first trim the project down a little.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Delete the entire &lt;em&gt;Account&lt;/em&gt; folder under /Views/. 
&lt;/li&gt;
&lt;li&gt;
Delete &lt;em&gt;AccountController.cs&lt;/em&gt; from the Controllers folder. 
&lt;/li&gt;
&lt;li&gt;
Delete shared partial view &lt;em&gt;/Views/Shared/LogOnUserControl.ascx&lt;/em&gt;. 
&lt;/li&gt;
&lt;li&gt;
Delete reference to this partial view by removing the &amp;quot;LoginDisplay&amp;quot; DIV
from&lt;em&gt; /Views/Shared/Site.Master&lt;/em&gt;, lines 18-20. 
&lt;/li&gt;
&lt;li&gt;
Removing &lt;em&gt;LoginDisplay&lt;/em&gt; will cause a slight layout problem from the CSS. To
fix it, modify the &lt;em&gt;#menucontainer&lt;/em&gt; definition in &lt;em&gt;/Content/Site.css&lt;/em&gt; on
line 263. 
&lt;br /&gt;
&lt;pre class="css:nocontrols" name="code"&gt;#menucontainer
{
    padding-top:40px;
}&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Save all, compile, and Run. The site should be functioning normally, but without the
Log In link in the top right of the home page. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Creating a Database
&lt;/h4&gt;
&lt;p&gt;
Like any dynamic web site, we need a storage mechanism. Create a database in SQL Server
or SQL Server Express with an Employee table containing columns for name, job title,
hired date, and termination date, as well as an identity column for finding records.&lt;a href="http://www.cptloadtest.com/content/binary/WindowsLiveWriter/ASP.NETMVCJamSession_14C62/MvcJamSession-EmployeeTable_1.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 5px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="MvcJamSession-EmployeeTable" border="0" alt="MvcJamSession-EmployeeTable" align="right" src="http://www.cptloadtest.com/content/binary/WindowsLiveWriter/ASP.NETMVCJamSession_14C62/MvcJamSession-EmployeeTable_thumb_1.jpg" width="250" height="283" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
For those with SQL Server Express, create a new database through right-clicking the
App_Data folder, and adding a new item. The new item should be a SQL Server Database. 
&lt;/li&gt;
&lt;li&gt;
For those with SQL Server, create a new database through SQL Server Management Studio
(SSMS). 
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
Create a new table called &lt;em&gt;Employee&lt;/em&gt;. 
&lt;/li&gt;
&lt;li&gt;
Create the following columns within the new table: 
&lt;ul&gt;
&lt;li&gt;
Id (primary key, identity, int, not null) 
&lt;/li&gt;
&lt;li&gt;
Name (varchar(50), not null) 
&lt;/li&gt;
&lt;li&gt;
JobTitle (varchar(50), not null) 
&lt;/li&gt;
&lt;li&gt;
HiredOn (date, not null) 
&lt;/li&gt;
&lt;li&gt;
TerminatedOn (date, null) 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Add a record or two to the table for good measure. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Creating a Model
&lt;/h4&gt;
&lt;p&gt;
The next thing we need to create is our Model. Not only is it the code representation
for our business entity (An Employee class contains Name, JobTitle, HiredOn, and TerminatedOn
properties), it is also responsible for &lt;em&gt;how&lt;/em&gt; to get, save, or delete data
from the database. We will be using Microsoft Entity Framework through Visual Studio
to generate our model for us.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
To create our new Model, right-click the &lt;em&gt;Model&lt;/em&gt; folder and select Add New
Item. The new item should be an ADO.NET Entity Data Model, found within the Data category
of the Add New Item dialog. Name it MvcJamSessionEntities. 
&lt;/li&gt;
&lt;li&gt;
Generate the Model from a database, connecting to your MVC Jam Session database created
in the previous section. On the step where you select your database connection, be
sure to allow Visual Studio to add the connection string to your web.config by checking
the appropriate checkbox. 
&lt;/li&gt;
&lt;li&gt;
The &lt;em&gt;Employee&lt;/em&gt; table is the only Data Object that needs to be generated. 
&lt;/li&gt;
&lt;li&gt;
When the dialog completes, your Entity Data Model (a .edmx file) should be displayed
in design view. 
&lt;/li&gt;
&lt;li&gt;
Save all and compile. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Creating a Controller
&lt;/h4&gt;
&lt;p&gt;
Now that our model is in place, we need to create a controller. The controller is
responsible for managing all interaction between the end-user and the application,
including identifying what data to get, save, or delete. (Remember, though the Controller
is responsible for &lt;em&gt;what&lt;/em&gt;, the Model is responsible for &lt;em&gt;how&lt;/em&gt;.)
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
To create our new Controller, right-click the &lt;em&gt;Controller&lt;/em&gt; folder and select
Add Controller. Since the name matters in ASP.NET MVC's convention-over-configuration
style, name it EmployeeController.cs (or .vb, if you happen to be working in Visual
Basic .NET). Be sure to check the &amp;quot;Add action methods for Create, Update, Detail,
and Delete scenarios&amp;quot; as we will be using them later. 
&lt;/li&gt;
&lt;li&gt;
We now have a basic controller, but it doesn't do anything yet. First, we want to
modify our Index action, as it is the default action in the controller. We will use
this action to list all of the Employees that currently exist in our database. Your
Index() action method should contain the following code: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;var _entities = new MvcJamSession.Models.MvcJamSessionEntities();
return View(_entities.Employee.ToList());&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Save all and compile. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Creating a View
&lt;/h4&gt;
&lt;p&gt;
We have our Model and we have our Controller, so it is time for our View. The View
is responsible for display only—it should contain virtually no logic. Our controller
doesn't do anything yet, but we can at least get the base file structure and navigation
in place. Since our Model governs &lt;em&gt;how&lt;/em&gt; and our Controller governs &lt;em&gt;what&lt;/em&gt;,
think of the View as governing &lt;em&gt;where&lt;/em&gt;, as it is responsible for deciding where
each data element gets displayed on your page.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Once you have saved and compiled your Controller, right-click on the Index action
name and select Add View. 
&lt;/li&gt;
&lt;li&gt;
The View should be named Index, just like your Controller action. Also, make your
View strongly typed to the Employee model. Since a list of Employees is being passed
to the View from the Controller, making the View strongly-typed prevents us from having
to cast our View Model from object to Employee. Finally, since we are providing a
list of Employees, the View Content should be a List. 
&lt;/li&gt;
&lt;li&gt;
The &lt;em&gt;Employee&lt;/em&gt; folder should be automatically created under the &lt;em&gt;/Views/&lt;/em&gt; folder,
and the &lt;em&gt;Index.aspx&lt;/em&gt; View inside of this new &lt;em&gt;Employee&lt;/em&gt; folder. 
&lt;/li&gt;
&lt;li&gt;
The last thing we need to do is provide some navigation to this view. Open up &lt;em&gt;/Views/Shared/Site.Master&lt;/em&gt; and
add an ActionLink within the Menu Container section to the Index action of the Employee
controller. When you are done, the Menu Container should look like this: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;&amp;lt;ul id=&amp;quot;menu&amp;quot;&amp;gt;              
  &amp;lt;li&amp;gt;&amp;lt;%= Html.ActionLink(&amp;quot;Home&amp;quot;, &amp;quot;Index&amp;quot;, &amp;quot;Home&amp;quot;)%&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;%= Html.ActionLink(&amp;quot;About&amp;quot;, &amp;quot;About&amp;quot;, &amp;quot;Home&amp;quot;)%&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;%= Html.ActionLink(&amp;quot;Employees&amp;quot;, &amp;quot;Index&amp;quot;, &amp;quot;Employee&amp;quot;)%&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Save all and run. When you navigate to your Employees link, you should get a list
of all employees currently in the database with an Edit, Details, and Delete links. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt; 
&lt;h5&gt;New in ASP.NET MVC 2: Strongly Typed HTML Helpers
&lt;/h5&gt;
&lt;p&gt;
In the previous version of ASP.NET MVC, HTML helpers were simple generic classes.
Generated views were full of Magic Strings for each property in your model, such as
&amp;lt;%= Html.TextBox(&amp;quot;Name&amp;quot;) %&amp;gt;, opening the door for a fat-fingered property
name. MVC 2 includes strongly-typed HTML helpers on strongly-typed views. For form-based
views, use the new strongly-typed &amp;quot;For&amp;quot; methods, such as &amp;lt;%= Html.TextBoxFor(model
=&amp;gt; model.Name) %&amp;gt; or &amp;lt;%= Html.EditorFor(model =&amp;gt; model.Name) %&amp;gt; to
eliminate the risk of incorrectly entering a property name. For display fields, use
Html.DisplayFor() to provide similar benefits for your read-only data, including the
elimination of HTML encoding for each field.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;h4&gt;Adding New Data
&lt;/h4&gt;
&lt;p&gt;
A list of employees is great, but we also need the ability to manipulate that data.
First, let's start with the ability to create new data.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Within Visual Studio, open &lt;em&gt;/Controllers/EmployeeController&lt;/em&gt; and navigate to
the POST Create action. POST is an HTTP verb associated with pushing data to the server
in the HTTP header, commonly associated with form submits. GET is the HTTP verb for
pure retrieval, commonly associated with a direct URL request, such as clicking a
link. In this case, the POST action can be identified by the [HttpPost] decoration. 
&lt;/li&gt;
&lt;li&gt;
The method arguments currently include only a FormCollection object that will contain
all of the header values associated with the POST. However, MVC is smart; it can automatically
transform this collection into a type-safe Model, based on the names of the header
variables (the identities of the HTML form inputs match the names of the Model's properties).
The one exception is the Id attribute, which is available in the Model but not populated
until after the object is saved to the database. To get strong typing, and avoid having
to manually cast or map form collection data to a new instance of our Model, change
the method signature to the following: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;public ActionResult Create([Bind(Exclude=&amp;quot;Id&amp;quot;)] Employee newEmployee)&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Now that we have a populated Model, we just need to save the Model to the database
and redirect back to the List when we are done. Do this by replacing the contents
of the action method with the following code: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;try
{
  if (!ModelState.IsValid) return View();

  var _entities = new MvcJamSession.Models.MvcJamSessionEntities();
  _entities.AddToEmployee(employee);
  _entities.SaveChanges();
  return RedirectToAction(&amp;quot;Index&amp;quot;);
}
catch
{
  return View();
}&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Save and compile. 
&lt;/li&gt;
&lt;li&gt;
Now we must create the View for adding data. As we did with Index, we can create the
view by right-clicking the Action method and selecting Add View. The view content
should be Create. 
&lt;/li&gt;
&lt;li&gt;
The only modification for the Create view is the Id property. The generated code creates
an input for this property, but it is not needed since the column value is auto-populated
by the database when saving the entity. Remove this input and label from the form. 
&lt;/li&gt;
&lt;li&gt;
Save and run. You should now be able to add new records to the database. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt; 
&lt;h5&gt;New in ASP.NET MVC2: Better Verb Attributes
&lt;/h5&gt;
&lt;p&gt;
In the first version of ASP.NET MVC, HTTP Verb conditions were placed on an Action
via the AcceptVerbsAttribute, such as the Create action's [AcceptVerbs(HttpVerbs.Post)].
In ASP.NET MVC 2, these attributes have been simplified with the introduction of the
HttpGetAttribute, HttpDeleteAttribute, HttpPostAttribute, and HttpPutAttribute.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;h4&gt;Routing and Updates
&lt;/h4&gt;
&lt;p&gt;
The end user can view a list of Employees, and can create new employees, but when
the end user clicks the Edit or Detail links, they get an error since these Views
haven't been created yet and the Actions are not implemented. One by one, we will
get the new views in place.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Within Visual Studio, open &lt;em&gt;/Controllers/EmployeeController&lt;/em&gt; and navigate to
the Details action. You may notice that the method already accepts an integer as input,
and shows example usage of the action in a commented URL above the method: &lt;em&gt;/Employee/Details/5&lt;/em&gt;.
This integer is the identity value of the Employee record, and is already populated
in the links of our List view created in the previous section. 
&lt;/li&gt;
&lt;li&gt;
Within Visual Studio, open &lt;em&gt;Global.asax&lt;/em&gt; and navigate to the RegisterRoutes
method. The default route for ASP.NET MVC is &lt;em&gt;/{controller}/{action}/{id}/&lt;/em&gt;.
By parsing out any URL into the application, MVC can determine which Controller to
use, which Action to execute, and which arguments to pass to the Action. Later portions
of the URL path are often optional, and when not specified, are replaced with the
default values: Home, Index, and String.Empty. The URLs of &amp;quot;/&amp;quot;, &amp;quot;/Home&amp;quot;,
&amp;quot;/Home/&amp;quot;, &amp;quot;/Home/Index&amp;quot;, and &amp;quot;/Home/Index/&amp;quot; are all
equivalent URLs in the eyes of ASP.NET MVC. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Go back to the Employee controller. Now that we know what the integer argument is
for, we need to retrieve the Employee matching the associated identity and pass it
to a view for editing or display.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Replace the contents of the GET version of the Edit action method with the following
code to retrieve the Employee from the database that matches the identity specified
in the route: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;var _entities = new MvcJamSession.Models.MvcJamSessionEntities();
return View(_entities.Employee.Where(emp =&amp;gt; emp.Id == id).First());&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Save and compile. 
&lt;/li&gt;
&lt;li&gt;
Right-click the Action and add the View. The View should still be strongly typed,
but this time the view content should be Edit. 
&lt;/li&gt;
&lt;li&gt;
The Details and GET Delete actions are largely similar as the GET Edit action, except
that the view is labels instead of text boxes. Repeat the above three steps for the
Details action method with a Details view content and for the GET Delete action method
with a Delete view content. 
&lt;/li&gt;
&lt;li&gt;
As with the Create view, the Id property should be removed from the Edit view, as
it is not an item that should be edited by the end user. 
&lt;/li&gt;
&lt;li&gt;
Save and run. You should see the details of an Employee when clicking on the Edit
and Details links. 
&lt;/li&gt;
&lt;li&gt;
We can view Employee details within the Edit form, but when we make changes and submit,
nothing happens. We need to modify the POST Edit action to save our changes back to
the database. The default POST Edit action accepts an id and a FormCollection as input
arguments, but similarly to the POST Create action, we can change this to use our
strongly typed model to avoid having to cast or map data. However, unlike our Create
action, we need to bind the id property so that the system knows which record to update.
To make these modifications, replace the POST Edit signature with the following: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;public ActionResult Edit(MvcJamSession.Models.Employee employee)&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Replace the contents of the POST Edit action method with the following code to save
the changes to the database: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;try
{
  if (!ModelState.IsValid) return View();

  var _entities = new MvcJamSession.Models.MvcJamSessionEntities();
  var _originalEmployee =
    _entities.Employee.Where(emp =&amp;gt; emp.Id == employee.Id).First();
  _entities.ApplyPropertyChanges(_originalEmployee.EntityKey.EntitySetName,
                                 employee);
  _entities.SaveChanges();
  return RedirectToAction(&amp;quot;Index&amp;quot;);
}
catch
{
  return View();
}&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Replace the signature of the POST Delete action method with the following code to
provide strong typing on our model: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;public ActionResult Delete(MvcJamSession.Models.Employee employee)&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Finally, replace the contents of the POST Delete action method with the following
code to delete a record: 
&lt;br /&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;var _entites = new MvcJamSession.Models.MvcJamSessionEntities();
var originalEmployee =
  _entites.Employee.Where(emp =&amp;gt; emp.Id == deletedEmployee.Id).First();
_entites.DeleteObject(originalEmployee);
_entites.SaveChanges();
return RedirectToAction(&amp;quot;Index&amp;quot;);&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Save, compile, and run. You should now be able to modify existing Employee records. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
We now have a fully-functional ASP.NET MVC application to manage our Employee records.
Congratulations!
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:13d5b303-4a7f-4ac9-93a3-f208ffe24fe0" class="wlWriterEditableSmartContent"&gt;Technorati
Tags: &lt;a href="http://technorati.com/tags/ASP.NET+MVC" rel="tag"&gt;ASP.NET MVC&lt;/a&gt;,&lt;a href="http://technorati.com/tags/MVC" rel="tag"&gt;MVC&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Jam+Session" rel="tag"&gt;Jam
Session&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Coding+Exercise" rel="tag"&gt;Coding
Exercise&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Learn+to+Code" rel="tag"&gt;Learn to
Code&lt;/a&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=1d5d9618-a51a-471f-a5ec-7381c916f11d" /&gt;</description>
      <comments>http://www.cptloadtest.com/CommentView,guid,1d5d9618-a51a-471f-a5ec-7381c916f11d.aspx</comments>
      <category>ASP.Net</category>
      <category>Learn to Code</category>
      <category>MVC</category>
    </item>
    <item>
      <trackback:ping>http://www.cptloadtest.com/Trackback.aspx?guid=f8562c46-4083-4d56-bc7c-42bff947af62</trackback:ping>
      <pingback:server>http://www.cptloadtest.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.cptloadtest.com/PermaLink,guid,f8562c46-4083-4d56-bc7c-42bff947af62.aspx</pingback:target>
      <dc:creator>Jay Harris</dc:creator>
      <wfw:comment>http://www.cptloadtest.com/CommentView,guid,f8562c46-4083-4d56-bc7c-42bff947af62.aspx</wfw:comment>
      <wfw:commentRss>http://www.cptloadtest.com/SyndicationService.asmx/GetEntryCommentsRss?guid=f8562c46-4083-4d56-bc7c-42bff947af62</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
On Tuesday, February 23rd, I will be leading the jam session for <a href="http://www.comejamwithus.org">Come
Jam With Us</a>, the software developer study group in Ann Arbor. The session will
be on ASP.NET MVC, and aims to give attendees enough of an introduction to the product
to empower developers to be able to start coding their own ASP.NET MVC 2 projects.
Like all of the Come Jam With Us sessions for the winter/spring of 2010, it will be
held at the offices of SRT Solutions in Ann Arbor at 5:30p.
</p>
        <h3>Prerequisites
</h3>
        <p>
You will need few things for ASP.NET MVC 2 application development and to complete
this exercise. Please complete the following prerequisites prior to the session, otherwise
you likely will spend the hour downloading and installing rather than coding.
</p>
        <ul>
          <li>
Install <a href="http://www.microsoft.com/visualstudio/">Microsoft Visual Studio 2008
SP1</a> or <a href="http://www.microsoft.com/express/Web/">Visual Web Developer 2008
Express</a> with SP1 
</li>
          <li>
Install <a href="http://www.microsoft.com/sqlserver/2008/">Microsoft SQL Server</a> or <a href="http://www.microsoft.com/express/Database/">SQL
Server Express</a></li>
          <li>
Download and install <a title="ASP.NET MVC 2 on Microsoft.com" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=7aba081a-19b9-44c4-a247-3882c8f749e3&amp;displaylang=en">ASP.NET
MVC 2 from Microsoft.com</a></li>
        </ul>
        <h3>Rescheduled
</h3>
        <p>
Due to weather, the original February 9th meeting was cancelled. This session is rescheduled
for Tuesday, February 23rd.
</p>
        <p>
        </p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a3e0d3cc-b34f-4985-84a1-155c955740ed" class="wlWriterEditableSmartContent">Technorati
Tags: <a href="http://technorati.com/tags/Ann+Arbor" rel="tag">Ann Arbor</a>,<a href="http://technorati.com/tags/Software" rel="tag">Software</a>,<a href="http://technorati.com/tags/Code+Jam" rel="tag">Code
Jam</a>,<a href="http://technorati.com/tags/Study+Group" rel="tag">Study Group</a>,<a href="http://technorati.com/tags/ASP.NET+MVC" rel="tag">ASP.NET
MVC</a>,<a href="http://technorati.com/tags/ASP.NET+MVC2" rel="tag">ASP.NET MVC2</a></div>
        <img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=f8562c46-4083-4d56-bc7c-42bff947af62" />
      </body>
      <title>Upcoming ASP.NET MVC 2 Study Group Jam Session in Ann Arbor</title>
      <guid isPermaLink="false">http://www.cptloadtest.com/PermaLink,guid,f8562c46-4083-4d56-bc7c-42bff947af62.aspx</guid>
      <link>http://www.cptloadtest.com/2010/02/08/Upcoming-ASPNET-MVC-2-Study-Group-Jam-Session-In-Ann-Arbor.aspx</link>
      <pubDate>Mon, 08 Feb 2010 04:45:36 GMT</pubDate>
      <description>&lt;p&gt;
On Tuesday, February 23rd, I will be leading the jam session for &lt;a href="http://www.comejamwithus.org"&gt;Come
Jam With Us&lt;/a&gt;, the software developer study group in Ann Arbor. The session will
be on ASP.NET MVC, and aims to give attendees enough of an introduction to the product
to empower developers to be able to start coding their own ASP.NET MVC 2 projects.
Like all of the Come Jam With Us sessions for the winter/spring of 2010, it will be
held at the offices of SRT Solutions in Ann Arbor at 5:30p.
&lt;/p&gt;
&lt;h3&gt;Prerequisites
&lt;/h3&gt;
&lt;p&gt;
You will need few things for ASP.NET MVC 2 application development and to complete
this exercise. Please complete the following prerequisites prior to the session, otherwise
you likely will spend the hour downloading and installing rather than coding.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Install &lt;a href="http://www.microsoft.com/visualstudio/"&gt;Microsoft Visual Studio 2008
SP1&lt;/a&gt; or &lt;a href="http://www.microsoft.com/express/Web/"&gt;Visual Web Developer 2008
Express&lt;/a&gt; with SP1 
&lt;/li&gt;
&lt;li&gt;
Install &lt;a href="http://www.microsoft.com/sqlserver/2008/"&gt;Microsoft SQL Server&lt;/a&gt; or &lt;a href="http://www.microsoft.com/express/Database/"&gt;SQL
Server Express&lt;/a&gt; 
&lt;/li&gt;
&lt;li&gt;
Download and install &lt;a title="ASP.NET MVC 2 on Microsoft.com" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=7aba081a-19b9-44c4-a247-3882c8f749e3&amp;amp;displaylang=en"&gt;ASP.NET
MVC 2 from Microsoft.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Rescheduled
&lt;/h3&gt;
&lt;p&gt;
Due to weather, the original February 9th meeting was cancelled. This session is rescheduled
for Tuesday, February 23rd.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a3e0d3cc-b34f-4985-84a1-155c955740ed" class="wlWriterEditableSmartContent"&gt;Technorati
Tags: &lt;a href="http://technorati.com/tags/Ann+Arbor" rel="tag"&gt;Ann Arbor&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Software" rel="tag"&gt;Software&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Code+Jam" rel="tag"&gt;Code
Jam&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Study+Group" rel="tag"&gt;Study Group&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ASP.NET+MVC" rel="tag"&gt;ASP.NET
MVC&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ASP.NET+MVC2" rel="tag"&gt;ASP.NET MVC2&lt;/a&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=f8562c46-4083-4d56-bc7c-42bff947af62" /&gt;</description>
      <comments>http://www.cptloadtest.com/CommentView,guid,f8562c46-4083-4d56-bc7c-42bff947af62.aspx</comments>
      <category>ASP.Net</category>
      <category>Events</category>
      <category>MVC</category>
    </item>
    <item>
      <trackback:ping>http://www.cptloadtest.com/Trackback.aspx?guid=9542d934-717f-4888-8164-5e0ba7843907</trackback:ping>
      <pingback:server>http://www.cptloadtest.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.cptloadtest.com/PermaLink,guid,9542d934-717f-4888-8164-5e0ba7843907.aspx</pingback:target>
      <dc:creator>Jay Harris</dc:creator>
      <wfw:comment>http://www.cptloadtest.com/CommentView,guid,9542d934-717f-4888-8164-5e0ba7843907.aspx</wfw:comment>
      <wfw:commentRss>http://www.cptloadtest.com/SyndicationService.asmx/GetEntryCommentsRss?guid=9542d934-717f-4888-8164-5e0ba7843907</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In ASP.NET MVC, the default signature for a Details action includes an Int32 method
argument. The system works fine when the expected data is entered, and the happy path
is followed, but put in an invalid value or no value at all, and an exception explodes
all over the user.
</p>
        <blockquote>
          <p style="color: maroon">
            <em>The parameters dictionary contains a null entry for parameter 'id' of non-nullable
type 'System.Int32' for method 'System.Web.Mvc.ActionResult Details(Int32)' in 'MvcSampleApplication.Controllers.WidgetController'.</em>
          </p>
        </blockquote>
        <p>
The following solution applies to the first version of the ASP.NET MVC framework.
If you are looking for a solution in the ASP.NET MVC 2 framework, try <a href="http://www.cptloadtest.com/2010/04/05/Validating-ASPNET-MVC-2-Route-Values-With-DefaultValueAttribute.aspx">Validating
ASP.NET MVC 2 Route Values with DefaultValueAttribute</a>.
</p>
        <p>
By default, the third section of an ASP.NET MVC Route is the Id, passed as a method
argument to a controller action. This value is a string, defaulting to String.Empty,
but it can be parsed to other types such as an integer for a default Details action.
The problem stems from when invalid values or missing values are passed to these integer-expecting
actions; MVC handles the inability to parse the value into an integer, but then throws
an exception trying to pass a null value to a Controller Action expecting a value
type for a method argument.
</p>
        <p>
A common solution is to convert the method argument to a nullable integer, which will
automatically cause the argument to be null when the route value specified in the
URL is an empty or non-integer value. The solution works fine, but seems a little
lame to me; I want to avoid having to check HasValue within every action. I have to
check for invalid identity values anyway (a user with an id of –1 isn’t going to exist
in my system), so I would much rather default these invalid integers to one of these
known, invalid values.
</p>
        <p>
Using a custom ActionFilterAttribute, I can accomplish my goal. Prior to executing
my Controller Action, an ActionFilterAttribute can validate that the specified route
value meets an expected type, and correct the value to a default value if this validation
fails; this will allowing me to keep that method argument as a value type integer
and avoid Nullable&lt;int&gt;.HasValue.
</p>
        <h3>
        </h3>
        <h3>ForceIntegerRouteValueAttribute class
</h3>
        <pre class="csharp:nocontrols" name="code">public sealed class ForceIntegerRouteValueAttribute : ActionFilterAttribute
{
  private readonly int _defaultValue;
  private readonly string _routeValueName;

  public ForceIntegerRouteValueAttribute(string valueName, int defaultValue)
  {
    _routeValueName = valueName;
    _defaultValue = defaultValue;
  }

  public override void OnActionExecuting(ActionExecutingContext context)
  {
    base.OnActionExecuting(context);

    int testValue;
    if (!context.ActionParameters.ContainsKey(_routeValueName) ||
        !int.TryParse(context.RouteData.Values[_routeValueName].ToString(),
                      out testValue))
    {
      context.RouteData.Values[_routeValueName] = _defaultValue;
      context.Result = new RedirectToRouteResult(context.RouteData.Values);
    }
  }
}</pre>
        <p>
The attribute accepts a string matching the name of the route value to analyze and
a default value to assign to the route value should the validation fail. The override
on OnActionExecuting will cause the validation to fire immediately prior to the Action
being executed. The method attempts to parse the route value to an integer, and if
it fails it will set the route value to the default value and restart processing of
the route. RedirectToRouteResult restarts the route processing over again, since to
get to this point, the method must have changed a route value, and without the redirect,
the action would continue on with the original value. This will also redirect the
browser to route matching the new route value, such as redirecting ~/Widgets/Details/Foo
to ~/Widgets/Details/0.
</p>
        <h3>Usage
</h3>
        <pre class="csharp:nocontrols" name="code">public class WidgetsController : Controller
{
  [ForceIntegerRouteValue("id", 0)]
  public ActionResult Details(int id)
  {
    return View();
  }
}</pre>
        <p>
By simply adding the attribute to the Action, I can now validate that my identity
is an integer, allowing for some level of trust into user input values, and do so
without having to laden my code with unnecessary value checks. This same idea can
be used for any sort of pre-filtering, which could also include checking that the
number contains no more than two decimal places. Just don’t go too far with this idea.
Familiarize yourself with Route Constraints, too, as there will be times that a constraint
can better serve your business needs than an Action Filter. But for areas where this
solution does serve well, such as eliminating Nullable&lt;int&gt; in Action arguments,
this option just seems cleaner to me. And in the ASP.NET MVC World of keeping Controllers
as light as possible, I like clean.
</p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:035a81e9-f452-4217-9318-7b1b84402f64" class="wlWriterEditableSmartContent">Technorati
Tags: <a href="http://technorati.com/tags/ASP.NET" rel="tag">ASP.NET</a>,<a href="http://technorati.com/tags/MVC" rel="tag">MVC</a>,<a href="http://technorati.com/tags/ActionFilterAttribute" rel="tag">ActionFilterAttribute</a></div>
        <img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=9542d934-717f-4888-8164-5e0ba7843907" />
      </body>
      <title>Validating ASP.NET MVC Route Values with ActionFilterAttribute</title>
      <guid isPermaLink="false">http://www.cptloadtest.com/PermaLink,guid,9542d934-717f-4888-8164-5e0ba7843907.aspx</guid>
      <link>http://www.cptloadtest.com/2009/12/01/Validating-ASPNET-MVC-Route-Values-With-ActionFilterAttribute.aspx</link>
      <pubDate>Tue, 01 Dec 2009 04:12:51 GMT</pubDate>
      <description>&lt;p&gt;
In ASP.NET MVC, the default signature for a Details action includes an Int32 method
argument. The system works fine when the expected data is entered, and the happy path
is followed, but put in an invalid value or no value at all, and an exception explodes
all over the user.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p style="color: maroon"&gt;
&lt;em&gt;The parameters dictionary contains a null entry for parameter 'id' of non-nullable
type 'System.Int32' for method 'System.Web.Mvc.ActionResult Details(Int32)' in 'MvcSampleApplication.Controllers.WidgetController'.&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The following solution applies to the first version of the ASP.NET MVC framework.
If you are looking for a solution in the ASP.NET MVC 2 framework, try &lt;a href="http://www.cptloadtest.com/2010/04/05/Validating-ASPNET-MVC-2-Route-Values-With-DefaultValueAttribute.aspx"&gt;Validating
ASP.NET MVC 2 Route Values with DefaultValueAttribute&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
By default, the third section of an ASP.NET MVC Route is the Id, passed as a method
argument to a controller action. This value is a string, defaulting to String.Empty,
but it can be parsed to other types such as an integer for a default Details action.
The problem stems from when invalid values or missing values are passed to these integer-expecting
actions; MVC handles the inability to parse the value into an integer, but then throws
an exception trying to pass a null value to a Controller Action expecting a value
type for a method argument.
&lt;/p&gt;
&lt;p&gt;
A common solution is to convert the method argument to a nullable integer, which will
automatically cause the argument to be null when the route value specified in the
URL is an empty or non-integer value. The solution works fine, but seems a little
lame to me; I want to avoid having to check HasValue within every action. I have to
check for invalid identity values anyway (a user with an id of –1 isn’t going to exist
in my system), so I would much rather default these invalid integers to one of these
known, invalid values.
&lt;/p&gt;
&lt;p&gt;
Using a custom ActionFilterAttribute, I can accomplish my goal. Prior to executing
my Controller Action, an ActionFilterAttribute can validate that the specified route
value meets an expected type, and correct the value to a default value if this validation
fails; this will allowing me to keep that method argument as a value type integer
and avoid Nullable&amp;lt;int&amp;gt;.HasValue.
&lt;/p&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;ForceIntegerRouteValueAttribute class
&lt;/h3&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;public sealed class ForceIntegerRouteValueAttribute : ActionFilterAttribute
{
  private readonly int _defaultValue;
  private readonly string _routeValueName;

  public ForceIntegerRouteValueAttribute(string valueName, int defaultValue)
  {
    _routeValueName = valueName;
    _defaultValue = defaultValue;
  }

  public override void OnActionExecuting(ActionExecutingContext context)
  {
    base.OnActionExecuting(context);

    int testValue;
    if (!context.ActionParameters.ContainsKey(_routeValueName) ||
        !int.TryParse(context.RouteData.Values[_routeValueName].ToString(),
                      out testValue))
    {
      context.RouteData.Values[_routeValueName] = _defaultValue;
      context.Result = new RedirectToRouteResult(context.RouteData.Values);
    }
  }
}&lt;/pre&gt;
&lt;p&gt;
The attribute accepts a string matching the name of the route value to analyze and
a default value to assign to the route value should the validation fail. The override
on OnActionExecuting will cause the validation to fire immediately prior to the Action
being executed. The method attempts to parse the route value to an integer, and if
it fails it will set the route value to the default value and restart processing of
the route. RedirectToRouteResult restarts the route processing over again, since to
get to this point, the method must have changed a route value, and without the redirect,
the action would continue on with the original value. This will also redirect the
browser to route matching the new route value, such as redirecting ~/Widgets/Details/Foo
to ~/Widgets/Details/0.
&lt;/p&gt;
&lt;h3&gt;Usage
&lt;/h3&gt;
&lt;pre class="csharp:nocontrols" name="code"&gt;public class WidgetsController : Controller
{
  [ForceIntegerRouteValue(&amp;quot;id&amp;quot;, 0)]
  public ActionResult Details(int id)
  {
    return View();
  }
}&lt;/pre&gt;
&lt;p&gt;
By simply adding the attribute to the Action, I can now validate that my identity
is an integer, allowing for some level of trust into user input values, and do so
without having to laden my code with unnecessary value checks. This same idea can
be used for any sort of pre-filtering, which could also include checking that the
number contains no more than two decimal places. Just don’t go too far with this idea.
Familiarize yourself with Route Constraints, too, as there will be times that a constraint
can better serve your business needs than an Action Filter. But for areas where this
solution does serve well, such as eliminating Nullable&amp;lt;int&amp;gt; in Action arguments,
this option just seems cleaner to me. And in the ASP.NET MVC World of keeping Controllers
as light as possible, I like clean.
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:035a81e9-f452-4217-9318-7b1b84402f64" class="wlWriterEditableSmartContent"&gt;Technorati
Tags: &lt;a href="http://technorati.com/tags/ASP.NET" rel="tag"&gt;ASP.NET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/MVC" rel="tag"&gt;MVC&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ActionFilterAttribute" rel="tag"&gt;ActionFilterAttribute&lt;/a&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.cptloadtest.com/aggbug.ashx?id=9542d934-717f-4888-8164-5e0ba7843907" /&gt;</description>
      <comments>http://www.cptloadtest.com/CommentView,guid,9542d934-717f-4888-8164-5e0ba7843907.aspx</comments>
      <category>ASP.Net</category>
      <category>MVC</category>
    </item>
  </channel>
</rss>