<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns: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:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>Steve Michelotti</title>
        <link>http://geekswithblogs.net/michelotti/Default.aspx</link>
        <description>C#, ASP.NET, and other stuff</description>
        <language>en-US</language>
        <copyright>Steve Michelotti</copyright>
        <managingEditor>steve.michelotti@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <image>
            <title>Steve Michelotti</title>
            <url>http://geekswithblogs.net/images/RSS2Image.gif</url>
            <link>http://geekswithblogs.net/michelotti/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/SteveMichelotti" type="application/rss+xml" /><item>
            <title>MVC Widgets with RenderAction</title>
            <category>.NET 3.5</category>
            <category>C# 3.0</category>
            <category>MVC</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/7VB8rA56kiY/mvc-widgets-with-renderaction.aspx</link>
            <description>&lt;p&gt;Last year when MVC was still in CTP, I blogged about using &lt;a href="http://geekswithblogs.net/michelotti/archive/2008/07/06/mvc-componentcontroller-vs.-viewusercontrol.aspx" target="_blank"&gt;MVC ComponentController and ViewUserControls&lt;/a&gt; to render widgets.  When MVC CTP4 was released, the ComponentController was eliminated from the framework and the RenderAction() helper method was introduced.  Rob Conery has a good post that discussed that &lt;a href="http://blog.wekeroad.com/blog/asp-net-mvc-preview-4-componentcontroller-is-now-renderaction/" target="_blank"&gt;here&lt;/a&gt;.  Despite the ComponentController being eliminated from the framework, I still frequently get questions about the older blog post as well as asking for the code sample to work with the current release of MVC.  I’ve updated the code to use the RenderAction() helper method and the new full code sample can be downloaded &lt;a href="https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=michelotti&amp;amp;ReleaseId=2988" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;But first, a couple of points.  By the time MVC was released the RenderAction method was moved to the MVC futures assembly.  The futures assembly can be download from CodePlex along with the rest of the MVC source &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471" target="_blank"&gt;here&lt;/a&gt;. Also, it is important to note that the RenderAction method is not without its share of controversy.  The argument against RenderAction is that it violates the separation of concerns that MVC is supposed to enforce – specifically that the views should have no knowledge of the controllers.  The argument on the other side is that sometimes breaking this rule is “pragmatic” and the views often have to know about controllers at least enough to be able to construct ActionLinks, etc. so this is not much different.  Both good arguments but from a “purist” point of view, it is definitely desirable to keep your views as lean as possible and, in general, not have knowledge of controllers.&lt;/p&gt;  &lt;p&gt;So revisiting the so-called “widget” example from last year’s post, let’s say you have a containing page where you want to have a bunch of widgets.  One way to render a widget would be to use RenderUserControl like this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.RenderUserControl(&lt;span class="str"&gt;"~/Views/Home/AddressEditor.ascx"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; AddressViewData(ViewData.Model.Contact.HomeAddress))&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;With this method you have to pass in the model from the containing page.  But if your containing page has 10 widgets then it’s not going to be very pretty to pass in 10 models to these various views.  And if they’re widgets, you want the logic more self contained for each widget – not just all on the parent containing page. In my previous post I showed calling a ComponentController’s action method via javascript like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    $(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        $(&lt;span class="str"&gt;'#secondWidget'&lt;/span&gt;).load(&lt;span class="str"&gt;'/Widget/Widget2'&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        $(&lt;span class="str"&gt;'#thirdWidget'&lt;/span&gt;).load(&lt;span class="str"&gt;'/Widget/Widget3'&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    });&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="secondWidget"&lt;/span&gt; &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;="widget"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="thirdWidget"&lt;/span&gt; &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;="widget"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This still works but since the ComponentController is gone, these just point normal Action methods.  The other way to do this is the use RenderAction like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="firstWidget"&lt;/span&gt; &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;="widget"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;Html.RenderAction&amp;lt;MvcWidget.Controllers.WidgetController&amp;gt;(c =&amp;gt; c.Widget1()); &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So, while this works just fine, you can now see concretely that the view has knowledge of the controller.  The upside is that the logic for passing the model to the view is encapsulated in the WidgetController rather than adding that responsibility to the containing page.  So, while not perfect, this is one way it can be handled in MVC. The complete code sample can be downloaded &lt;a href="https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=michelotti&amp;amp;ReleaseId=2988" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133521"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133521" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/133521.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/7VB8rA56kiY" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/07/15/mvc-widgets-with-renderaction.aspx</guid>
            <pubDate>Thu, 16 Jul 2009 02:35:12 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/133521.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/07/15/mvc-widgets-with-renderaction.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/133521.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/133521.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/07/15/mvc-widgets-with-renderaction.aspx</feedburner:origLink></item>
        <item>
            <title>SOMD NUG Presentation Code Samples &amp;ndash; Building and Consuming WCF 3.5 REST Services</title>
            <category>.NET 3.5</category>
            <category>C# 3.0</category>
            <category>Data Services</category>
            <category>Entity Framework</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/yf_N1mEYSJI/somd-nug-presentation-code-samples-ndash-building-and-consuming-wcf.aspx</link>
            <description>&lt;p&gt;Thanks to everyone who attended my presentation on WCF 3.5 REST services last night at SOMD NUG. The link to download both the code and power point is &lt;a href="https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=michelotti&amp;amp;ReleaseId=2635" target="_blank"&gt;here&lt;/a&gt;.  It also includes the SQL script for creating the database.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133498"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133498" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/133498.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/yf_N1mEYSJI" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/07/14/somd-nug-presentation-code-samples-ndash-building-and-consuming-wcf.aspx</guid>
            <pubDate>Wed, 15 Jul 2009 00:55:54 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/133498.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/07/14/somd-nug-presentation-code-samples-ndash-building-and-consuming-wcf.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/133498.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/133498.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/07/14/somd-nug-presentation-code-samples-ndash-building-and-consuming-wcf.aspx</feedburner:origLink></item>
        <item>
            <title>Presentation at SOMD NUG &amp;ndash; WCF 3.5 REST</title>
            <category>.NET 3.5</category>
            <category>C# 3.0</category>
            <category>Data Services</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/0y9bZ-EjB00/presentation-at-somd-nug-ndash-wcf-3.5-rest.aspx</link>
            <description>&lt;p&gt;Tomorrow I will be giving a presentation at &lt;a href="http://www.somd-dnug.org/"&gt;Southern Maryland .NET User Group&lt;/a&gt; on WCF 3.5 REST.  This demo-heavy presentation will cover both building and consuming WCF 3.5 REST services. We will dive into many of the new APIs available in the WCF REST Starter Kit with a nod to new features on the horizon in WCF 4.0. Consuming REST services will be explored through a pure AJAX jQuery client as well as a Silverlight client. The session will also give a brief introduction to ADO.NET Data Services.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133436"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133436" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/133436.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/0y9bZ-EjB00" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/07/12/presentation-at-somd-nug-ndash-wcf-3.5-rest.aspx</guid>
            <pubDate>Sun, 12 Jul 2009 18:55:25 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/133436.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/07/12/presentation-at-somd-nug-ndash-wcf-3.5-rest.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/133436.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/133436.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/07/12/presentation-at-somd-nug-ndash-wcf-3.5-rest.aspx</feedburner:origLink></item>
        <item>
            <title>Inheritance with ADO.NET Data Services and the Entity Framework</title>
            <category>.NET 3.5</category>
            <category>C# 3.0</category>
            <category>Data Services</category>
            <category>Entity Framework</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/eiiUGWAGlI0/inheritance-with-ado.net-data-services-and-the-entity-framework.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" target="_blank"&gt;ADO.NET Data Services&lt;/a&gt; provides a robust REST API over top of a data source. That data source could be 1) the Entity Framework (EF), 2) LINQ to SQL, or 3) your own custom data source that implements &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx" target="_blank"&gt;IQueryable&lt;/a&gt; and/or &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.services.iupdatable.aspx" target="_blank"&gt;IUpdatable&lt;/a&gt;.  However, it should be noted that in v1, EF is really the “first class” data source for ADO.NET Data Services because it supports both IQueryable and IUpdatable out of the box.  In this post I’ll discuss the scenario where you have inheritance in your entity object model and the pros and cons of the implementation. As a stand-alone ORM tool, EF has not always been extremely well received by the developer community especially in comparison to other tools such as &lt;a href="http://msdn.microsoft.com/en-us/library/bb386976.aspx" target="_blank"&gt;LINQ to SQL&lt;/a&gt; and &lt;a href="http://nhforge.org/" target="_blank"&gt;NHibernate&lt;/a&gt;.  While I generally share many of the frustrations of my fellow developers with EF, the 2 reasons I find it compelling enough to investigate further are: 1) it’s first class support for ADO.NET Data Services (and data services is great), and 2) the enhancements that are coming in EF vNext including &lt;a href="http://blogs.msdn.com/efdesign/archive/2009/06/10/code-only.aspx" target="_blank"&gt;Code Only&lt;/a&gt; with POCO which will bring EF much more in line with other ORM tools that already enable these POCO scenarios as well as &lt;a href="http://blogs.msdn.com/efdesign/archive/2008/09/10/model-first.aspx" target="_blank"&gt;Model First&lt;/a&gt; development.&lt;/p&gt;  &lt;p&gt;EF supports 3 types of inheritance: 1) Table per Hierarchy (aka Single Table Inheritance), 2) Table per Type, and 3) Table per Concrete Type.  In this example, I’ll be using the Table per Type (TPT) inheritance. I won’t cover every detail as to how I set up the TPT inheritance with EF but if you haven’t done it before then you should check out &lt;a href="http://blogs.msdn.com/bags/archive/2009/03/06/entity-framework-modeling-table-per-type-inheritance.aspx" target="_blank"&gt;this post here&lt;/a&gt; that covers step by step how to do it. In my scenario, suppose I have an EF model that looks like this:&lt;/p&gt;  &lt;p&gt; &lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_EntityDesignerDiagram.png" /&gt; &lt;/p&gt;  &lt;p&gt;Notice that I have a base class of Client which both Person and Business inherit from.  Additionally, a Person and a Business will have ClientAddresses (they inherit the addresses from the base Client class).  I add a new ADO.NET Data Service to my project which looks like this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ClientDataService : DataService&amp;lt;ClientEntities&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; InitializeService(IDataServiceConfiguration config)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        config.SetEntitySetAccessRule(&lt;span class="str"&gt;"*"&lt;/span&gt;, EntitySetRights.All);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that I named my EF object context “ClientEntities” so the DataService can be strongly-typed as shown above. Also note that I’m completely opening up my permissions to all entities by using the * wildcard in the SetEntitySetAccessRule() call above but in production you’d want to think through your permissions a little more than shown in my demo code above.&lt;/p&gt;

&lt;p&gt;Now at this point, if we fire up our data service we’ll see the default meta-data screen:&lt;/p&gt;

&lt;p&gt; &lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_DefaultDSPage.PNG" /&gt; &lt;/p&gt;

&lt;p&gt;This screen shows the entity sets I have available to query but interestingly it does not show that I have a Person or Business entity set available (more on that later).  So how do I get a Person or a Business object?  I just so happen to know that in my database, the ClientID of 1 is a Person and the ClientID of 2 is a Business.  If I do a query for a Client with these respective ClientID’s, it actually figures it out for you.&lt;/p&gt;

&lt;p&gt;Here is my query for a Client who is a Person:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_ClientPerson.PNG" /&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;And here is my query for Client who is a Business:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_ClientBusiness.PNG" /&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Data Services in conjunction with EF will correctly instantiate the correct concrete type. In one regard, this is great.  But on the other hand, this isn’t very explicit.  The URI I used was: /Clients(2).  Wouldn’t it have been more explicit if I could have used the URI of /Persons(2)?  After all, that is the name of my EntitySet.  But *actually* it’s not the name of my EntitySet.  In these inheritance situations, EF allows you to specify the Entity Set Name for the base type, but it does not allow you the set the Entity Set Name for the sub-class – that just takes the same Entity Set Name as it’s base class. One way for us to use a more intuitive URI would be to create a Service Operation like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[WebGet]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; IQueryable&amp;lt;Person&amp;gt; Persons()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    var results = from c &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.CurrentDataSource.Clients&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;                  &lt;span class="kwrd"&gt;where&lt;/span&gt; c.ClientType == &lt;span class="str"&gt;"PERSON"&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;                  select c;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; results.ToList().Cast&amp;lt;Person&amp;gt;().AsQueryable();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note you must also enable permissions to this new service operation by adding this line of code your your InitializeService() method:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;config.SetServiceOperationAccessRule(&lt;span class="str"&gt;"Persons"&lt;/span&gt;, ServiceOperationRights.All);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So now you are able to get a Person object with a more explicit and “strongly-typed” URI like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_PersonURI.PNG" /&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;This is all well and good but it does have some drawbacks.  For one thing, this service operation does not appear on the default page that shows all the meta data for the data service so the discoverability for something like this is not great.  Additionally, on the client side, the consuming developer will also have to understand these implementation details and handle the casting on their end if they’re consuming data services in the default fashion with the data services proxy.  Therefore, while I’ve found this scenario to be *possible* with Data Services and EF, I don’t really put it in the category of extremely user friendly.  However, these drawbacks seem to be more of a function of the implementation of EF than ADO.NET Data Services so I’m still a fan of data services.  It will be interesting to see how the enhancements in EF 4.0 (especially with the renewed emphasis on POCO) will change the game with scenarios like these.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133059"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=133059" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/133059.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/eiiUGWAGlI0" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/06/25/inheritance-with-ado.net-data-services-and-the-entity-framework.aspx</guid>
            <pubDate>Fri, 26 Jun 2009 09:29:41 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/133059.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/06/25/inheritance-with-ado.net-data-services-and-the-entity-framework.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/133059.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/133059.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/06/25/inheritance-with-ado.net-data-services-and-the-entity-framework.aspx</feedburner:origLink></item>
        <item>
            <title>MVC HTML Helper &amp;ndash; SubmitLink</title>
            <category>C# 3.0</category>
            <category>.NET 3.5</category>
            <category>MVC</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/G6jhgUC7wqw/mvc-html-helper-ndash-submitlink.aspx</link>
            <description>&lt;p&gt;Often when creating web applications, it’s common for us to want to submit or post forms to the server by using a hyperlink rather than an HTML submit button.  It might be visually more appealing/consistent or whatever your reason might be to have your buttons look like this:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_SaveCancel.PNG" /&gt; &lt;/p&gt;  &lt;p&gt;The Cancel button is easy because we can just use a normal Hmtl.ActionLink helper to redirect to whatever our cancel page is.  But what to do for the Save link given that we don’t have anything in MVC out of the box that is analogous to the LinkButton in ASP.NET web forms?  One solution might be to just use JavaScript like this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;a&lt;/span&gt; &lt;span class="attr"&gt;href&lt;/span&gt;&lt;span class="kwrd"&gt;="javascript:document.mainForm.submit();"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Save&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;a&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ActionLink(&lt;span class="str"&gt;"Cancel"&lt;/span&gt;, &lt;span class="str"&gt;"Index"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;But that is somewhat ugly and the paradigm is inconsistent with the Cancel button where we’re using a normal ActionLink.  An alternative for this scenario is to just create a simple SubmitLink HTML helper that will allow you’re code to look like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.SubmitLink(&lt;span class="str"&gt;"Save"&lt;/span&gt;, &lt;span class="str"&gt;"mainForm"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ActionLink(&lt;span class="str"&gt;"Cancel"&lt;/span&gt;, &lt;span class="str"&gt;"Index"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can see this allows us to have a consistent coding paradigm.  The first argument is the link text and the second is the form name.  The implementation looks like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; SubmitLink(&lt;span class="kwrd"&gt;this&lt;/span&gt; HtmlHelper htmlHelper, &lt;span class="kwrd"&gt;string&lt;/span&gt; linkText, &lt;span class="kwrd"&gt;string&lt;/span&gt; formName, &lt;span class="kwrd"&gt;object&lt;/span&gt; htmlAttributes)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    TagBuilder tagBuilder = &lt;span class="kwrd"&gt;new&lt;/span&gt; TagBuilder(&lt;span class="str"&gt;"a"&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    tagBuilder.MergeAttribute(&lt;span class="str"&gt;"href"&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"javascript:document.{0}.submit();"&lt;/span&gt;, formName));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    tagBuilder.MergeAttributes(&lt;span class="kwrd"&gt;new&lt;/span&gt; RouteValueDictionary(htmlAttributes));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    tagBuilder.InnerHtml = linkText;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; tagBuilder.ToString();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; SubmitLink(&lt;span class="kwrd"&gt;this&lt;/span&gt; HtmlHelper htmlHelper, &lt;span class="kwrd"&gt;string&lt;/span&gt; linkText, &lt;span class="kwrd"&gt;string&lt;/span&gt; formName)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; htmlHelper.SubmitLink(linkText, formName, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice there is an overload to takes htmlAttributes so that you can apply any arbitrary attributes you might want.  For example, you might want to apply a CSS class that looks like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.SubmitLink(&lt;span class="str"&gt;"Save"&lt;/span&gt;, &lt;span class="str"&gt;"mainForm"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; { @&lt;span class="kwrd"&gt;class&lt;/span&gt; = &lt;span class="str"&gt;"foo"&lt;/span&gt; }) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;These types of little HTML helpers are so easy to build with MVC, especially given that we can use the TagBuilder class, that it really enables a lot of re-use across your applications.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132592"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=132592" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/132592.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/G6jhgUC7wqw" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/06/03/mvc-html-helper-ndash-submitlink.aspx</guid>
            <pubDate>Thu, 04 Jun 2009 01:56:43 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/132592.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/06/03/mvc-html-helper-ndash-submitlink.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/132592.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/132592.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/06/03/mvc-html-helper-ndash-submitlink.aspx</feedburner:origLink></item>
        <item>
            <title>My Visual Studio Shortcuts and Macros</title>
            <category>General</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/bUTIGmiiKA0/my-visual-studio-shortcuts-and-macros.aspx</link>
            <description>&lt;p&gt;Often when I give presentations, I’m asked afterwards what Visual Studio add-ins I was using. The fact is that most of what you’re seeing are not expensive add-ins at all but either built-in Visual Studio functionality or custom Visual Studio macros that I have written and bound to keyboard shortcuts which give the appearance that they’re “built in” to Visual Studio.  The following 4 minute video shows how I use these shortcuts to maintain a fast pace during my presentations and not bore the audience with a whole bunch of repetitive typing.  The code for these visual studio macros can be found &lt;a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=michelotti&amp;amp;DownloadId=5699" target="_blank"&gt;here&lt;/a&gt;.  The complete list of developer tools that I use on a daily basis can be found &lt;a href="http://geekswithblogs.net/michelotti/archive/2008/11/23/developer-tools-and-utilities.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt; &lt;object name="Video" classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715" standby="Loading Microsoft Windows Media Player components..." type="application/x-oleobject" width="640" height="545"&gt; &lt;param name="url" value="http://content.screencast.com/users/smichelotti/folders/Default/media/efcf99c5-afa0-43b9-9660-bfe487dae4fa/vs-shortcuts.wmv" /&gt; &lt;param name="AutoStart" value="0" /&gt; &lt;param name="ShowControls" value="true" /&gt; &lt;param name="uiMode" value="full" /&gt; &lt;param name="playCount" value="1" /&gt; &lt;param name="CurrentPosition" value="0" /&gt; &lt;embed name="Video" type="application/x-mplayer2" src="http://content.screencast.com/users/smichelotti/folders/Default/media/efcf99c5-afa0-43b9-9660-bfe487dae4fa/vs-shortcuts.wmv" autostart="0" showcontrols="1" uimode="full" playcount="1" currentposition="0" width="640" height="545"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131912"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131912" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/131912.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/bUTIGmiiKA0" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/05/08/my-visual-studio-shortcuts-and-macros.aspx</guid>
            <pubDate>Sat, 09 May 2009 04:23:48 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/131912.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/05/08/my-visual-studio-shortcuts-and-macros.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/131912.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/131912.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/05/08/my-visual-studio-shortcuts-and-macros.aspx</feedburner:origLink></item>
        <item>
            <title>CMAP Presentation Code Samples &amp;ndash; Building and Consuming WCF 3.5 REST Services</title>
            <category>.NET 3.5</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/X06nZg60XcM/cmap-presentation-code-samples-ndash-building-and-consuming-wcf-3.5.aspx</link>
            <description>&lt;p&gt;Thanks to everyone who attended my presentation last night at CMAP.  The link to download both the code and power point is &lt;a href="https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=michelotti&amp;amp;ReleaseId=2635" target="_blank"&gt;here&lt;/a&gt;.  It also includes the SQL script for creating the database.&lt;/p&gt;  &lt;p&gt;I was asked what tool I was using for zooming – it was ZoomIt (which is free).  The link to ZoomIt (plus other tools) can be found &lt;a href="http://geekswithblogs.net/michelotti/archive/2008/11/23/developer-tools-and-utilities.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131850"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131850" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/131850.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/X06nZg60XcM" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/05/06/cmap-presentation-code-samples-ndash-building-and-consuming-wcf-3.5.aspx</guid>
            <pubDate>Wed, 06 May 2009 23:05:50 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/131850.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/05/06/cmap-presentation-code-samples-ndash-building-and-consuming-wcf-3.5.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/131850.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/131850.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/05/06/cmap-presentation-code-samples-ndash-building-and-consuming-wcf-3.5.aspx</feedburner:origLink></item>
        <item>
            <title>CMAP Presentation &amp;ndash; Building and Consuming WCF 3.5 REST Services</title>
            <category>.NET 3.5</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/McP8DFJsx00/cmap-presentation-ndash-building-and-consuming-wcf-3.5-rest-services.aspx</link>
            <description>&lt;p&gt;Next Tuesday (May 5), I will be presenting WCF 3.5 REST Services at CMAP.  Details here: &lt;a href="http://www.cmap-online.org/Meetings/Details/2009-05-05.aspx" target="_blank"&gt;http://www.cmap-online.org/Meetings/Details/2009-05-05.aspx&lt;/a&gt; .&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131652"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131652" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/131652.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/McP8DFJsx00" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/05/01/cmap-presentation-ndash-building-and-consuming-wcf-3.5-rest-services.aspx</guid>
            <pubDate>Fri, 01 May 2009 23:34:58 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/131652.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/05/01/cmap-presentation-ndash-building-and-consuming-wcf-3.5-rest-services.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/131652.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/131652.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/05/01/cmap-presentation-ndash-building-and-consuming-wcf-3.5-rest-services.aspx</feedburner:origLink></item>
        <item>
            <title>Richmond Code Camp &amp;ndash; code samples</title>
            <category>C# 3.0</category>
            <category>LINQ</category>
            <category>.NET 3.5</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/rFtge5Da92o/richmond-code-camp-ndash-code-samples.aspx</link>
            <description>&lt;p&gt;For those of you who attended my presentation this past weekend at the Richmond Code Camp, you can download the code samples that I used during my presentation &lt;a href="http://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=michelotti&amp;amp;ReleaseId=938" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131488"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=131488" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/131488.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/rFtge5Da92o" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/04/27/richmond-code-camp-ndash-code-samples.aspx</guid>
            <pubDate>Mon, 27 Apr 2009 22:23:57 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/131488.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/04/27/richmond-code-camp-ndash-code-samples.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/131488.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/131488.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/04/27/richmond-code-camp-ndash-code-samples.aspx</feedburner:origLink></item>
        <item>
            <title>MVC DeleteLink with AjaxHelper</title>
            <category>.NET 3.5</category>
            <category>C# 3.0</category>
            <category>MVC</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/LSQUfiSe6SU/mvc-deletelink-with-ajaxhelper.aspx</link>
            <description>&lt;p&gt;Relatively recently it was discovered that the MVC framework was inadvertently leading to some bad practices around deleting resources with HTTP GET requests.  Specifically, HTTP best practices (and &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank"&gt;RESTful&lt;/a&gt; best practices) state that GET requests should never modify resources. Some people consider this a “security” hole and, while that may be true, I consider it more of a “best practices” hole.  &lt;a href="http://stephenwalther.com/blog/" target="_blank"&gt;Stephen Walther&lt;/a&gt; has a great post on this topic &lt;a href="http://stephenwalther.com/blog/archive/2009/01/21/asp.net-mvc-tip-46-ndash-donrsquot-use-delete-links-because.aspx" target="_blank"&gt;here&lt;/a&gt;. In his post, Walther demonstrates two different alternatives to using a normal HtmlHelper ActionLink: 1) Ajax Deletes and 2) nested forms with image buttons. &lt;/p&gt;  &lt;p&gt;In this post, I’m simply going to show an alternative implementation to his first option of the Ajax Delete.&lt;/p&gt;  &lt;p&gt;Let’s say you have a list of contacts in a grid like this:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_contacts.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;with markup that looks like this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ActionLink(&lt;span class="str"&gt;"Add New Contact"&lt;/span&gt;, &lt;span class="str"&gt;"Create"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;table&lt;/span&gt; &lt;span class="attr"&gt;cellspacing&lt;/span&gt;&lt;span class="kwrd"&gt;="0"&lt;/span&gt; &lt;span class="attr"&gt;cellpadding&lt;/span&gt;&lt;span class="kwrd"&gt;="4"&lt;/span&gt; &lt;span class="attr"&gt;border&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt; &lt;span class="attr"&gt;scope&lt;/span&gt;&lt;span class="kwrd"&gt;="col"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt; &lt;span class="attr"&gt;scope&lt;/span&gt;&lt;span class="kwrd"&gt;="col"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt; &lt;span class="attr"&gt;scope&lt;/span&gt;&lt;span class="kwrd"&gt;="col"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt; &lt;span class="attr"&gt;scope&lt;/span&gt;&lt;span class="kwrd"&gt;="col"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;span class="attr"&gt;&amp;amp;nbsp;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt; &lt;span class="attr"&gt;scope&lt;/span&gt;&lt;span class="kwrd"&gt;="col"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;span class="attr"&gt;&amp;amp;nbsp;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;th&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (GetContactListResult contact &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Model) { &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=contact.FirstName &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=contact.LastName &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=contact.Email &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;                &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ActionLink(&lt;span class="str"&gt;"Edit"&lt;/span&gt;, &lt;span class="str"&gt;"Create"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; { id = contact.ContactID }) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;                &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ActionLink(&lt;span class="str"&gt;"Delete"&lt;/span&gt;, &lt;span class="str"&gt;"Delete"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; { id = contact.ContactID }) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;td&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;tr&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt; } &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;table&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;On line #21 you will see the line that is the common offender – a hyperlink which will result in a GET request to delete a record to this corresponding Action Method:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; RedirectToRouteResult Delete(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.contactManager.DeleteContact(id);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; RedirectToAction(&lt;span class="str"&gt;"Index"&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In Walther’s post, he uses the raw Sys.Net.WebRequest object to perform his Ajax operations.  Here I’m going to start out an alternative implementation but using an AjaxHelper. First off, we can change line #21 above to this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Ajax.ActionLink(&lt;span class="str"&gt;"Delete"&lt;/span&gt;, &lt;span class="str"&gt;"Delete"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; { id = contact.ContactID }, &lt;span class="kwrd"&gt;new&lt;/span&gt; AjaxOptions&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;                                                                        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;                                                                            Confirm = &lt;span class="str"&gt;"Are you sure you want to delete?"&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;                                                                            OnComplete = &lt;span class="str"&gt;"deleteComplete"&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;                                                                            HttpMethod = &lt;span class="str"&gt;"DELETE"&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;                                                                        })&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The first three arguments (link text, action name, and route values) match the original implementation exactly but note the AjaxOptions in the fourth parameter. We have a nice little confirm message that will be displayed in a JavaScript prompt. You also see that the OnComplete property is pointing to a function delegate called “deleteComplete” to invoke after the Ajax call has completed.  Finally, we’re specifying “DELETE” for the HTTP verb.  There are a couple of additional items that you have to do to make this work.  Specifically, we need to add this script block to the head section of our page:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="/Scripts/MicrosoftAjax.js"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&amp;lt;script src=&lt;span class="str"&gt;"/Scripts/MicrosoftMvcAjax.js"&lt;/span&gt; type=&lt;span class="str"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&amp;lt;script type=&lt;span class="str"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;function&lt;/span&gt; deleteComplete() {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        window.location.reload();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice we have to include the Microsoft javascript libraries to ensure the the AjaxHelper methods will work correctly. Also, I’m defining a simple callback to reload the page. If you refer back to my original Delete() action method, it is returning a RedirectToRouteResult.  Additionally, we now need to make a couple of changes to our Delete() action method like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[AcceptVerbs(HttpVerbs.Delete)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ContentResult Delete(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.contactManager.DeleteContact(id);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Content(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice it is now allowing *only* requests for the DELETE verb. If a GET request for this URI is issued, it will result in a 404. I also have to return an empty ContentResult since the javascript is now going to do my redirect client side.  So this will be an incredibly lightweight Ajax server call.&lt;/p&gt;

&lt;p&gt;As another alternative, you could even write your action method using an EmptyResult type like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[AcceptVerbs(HttpVerbs.Delete)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; EmptyResult Delete(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.contactManager.DeleteContact(id);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now when we click the delete link, we can see the request via the &lt;a href="http://projects.nikhilk.net/WebDevHelper/" target="_blank"&gt;Web Development Helper IE add-in&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_ajaxDelete.jpg" /&gt; &lt;/p&gt;

&lt;p&gt;You’ll see we’re now issuing the request with a DELETE verb and the server is returning a 200. Behind the scenes, the AjaxHelper is using the XMLHttpRequest object.  One little side note, it order to make the request show up correctly in the web dev helper add-in, I had to change line #5 of my Action method to this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Content(&lt;span class="str"&gt;" "&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I’m considering this a bug in the web dev helper because both an empty string and a space work just fine at run-time.&lt;/p&gt;

&lt;p&gt;This is all well and good but the one thing is that our AjaxHelper ActionLink is a little verbose.  If I’m going to be having Delete links in multiple places in my app, I sure &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself" target="_blank"&gt;don’t want to have to repeat this same thing all over the place&lt;/a&gt;. I also don’t want to have to put in the same 1-line javascript callback function every time just to do a little redirect. In order to accomplish this, I can write my own little AjaxHelper method called “DeleteLink” that will allow me to change my mark-up to the much simpler version *and* avoid having to include an inline javascript callback like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Ajax.DeleteLink(&lt;span class="str"&gt;"Delete"&lt;/span&gt;, &lt;span class="str"&gt;"Delete"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; { id = contact.ContactID }) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Creating your own Html or Ajax Helper in MVC is typically a pretty straightforward process (*much* easier than creating ASP.NET server controls for example). The complete implementation for my DeleteLink helper method is:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; DeleteLink(&lt;span class="kwrd"&gt;this&lt;/span&gt; AjaxHelper ajaxHelper, &lt;span class="kwrd"&gt;string&lt;/span&gt; linkText, &lt;span class="kwrd"&gt;string&lt;/span&gt; actionName, &lt;span class="kwrd"&gt;object&lt;/span&gt; routeValues)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; ajaxHelper.ActionLink(linkText, actionName, routeValues, &lt;span class="kwrd"&gt;new&lt;/span&gt; AjaxOptions&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        Confirm = &lt;span class="str"&gt;"Are you sure you want to delete this item?"&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        HttpMethod = &lt;span class="str"&gt;"DELETE"&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        OnSuccess = &lt;span class="str"&gt;"function() { window.location.reload(); }"&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    });&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice that I’ve inlined the javascript function to reload the page.  Other than that, everything has just been moved into this method to encapsulate it here.  This method could be further customized to include overloads for htmlAttributes, alternative link text, or more. You could also extend this sample by making it more robust by adding a callback for the OnFailure property.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130789"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130789" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/130789.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/LSQUfiSe6SU" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/04/06/mvc-deletelink-with-ajaxhelper.aspx</guid>
            <pubDate>Tue, 07 Apr 2009 09:19:04 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/130789.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/04/06/mvc-deletelink-with-ajaxhelper.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/130789.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/130789.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/04/06/mvc-deletelink-with-ajaxhelper.aspx</feedburner:origLink></item>
        <item>
            <title>Microsoft Tech Days code sample</title>
            <category>.NET 3.5</category>
            <category>C# 3.0</category>
            <category>MVC</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/e0VZUKe0hS8/microsoft-tech-days-code-sample.aspx</link>
            <description>&lt;p&gt;Thanks to everyone who attended my session today on ASP.NET MVC at &lt;a href="http://www.msfttechdays.com/dac/" target="_blank"&gt;Microsoft Tech Days&lt;/a&gt;.  You can download the code sample that was build &lt;a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=michelotti&amp;amp;DownloadId=3437" target="_blank"&gt;here&lt;/a&gt;.  Let me know if any questions.  Thanks.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130645"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130645" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/130645.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/e0VZUKe0hS8" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/04/01/microsoft-tech-days-code-sample.aspx</guid>
            <pubDate>Thu, 02 Apr 2009 02:44:03 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/130645.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/04/01/microsoft-tech-days-code-sample.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/130645.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/130645.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/04/01/microsoft-tech-days-code-sample.aspx</feedburner:origLink></item>
        <item>
            <title>Enterprise Library Validation Application Block with MVC Binders</title>
            <category>Enterprise Library</category>
            <category>C# 3.0</category>
            <category>.NET 3.5</category>
            <category>MVC</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/vIMUyeM-xeo/enterprise-library-validation-application-block-with-mvc-binders.aspx</link>
            <description>&lt;p&gt;A while back, I blogged about using the &lt;a href="http://geekswithblogs.net/michelotti/archive/2008/10/04/enterprise-library-validation-application-block-with-asp.net-mvc.aspx" target="_blank"&gt;Enterprise Library Validation Application Block (VAB) with ASP.NET MVC&lt;/a&gt;. As MVC has matured as a framework, this scenario has becoming simpler.  In early releases of MVC, I implemented the execution of the VAB validation in the controller methods.  However, I now prefer to put that logic in the binders themselves.  In earlier versions of the framework, the model binders that came out of the box dealt well with simple objects but if you had more complex View Models (&lt;a href="http://geekswithblogs.net/michelotti/archive/2008/10/04/enterprise-library-validation-application-block-with-asp.net-mvc.aspx" target="_blank"&gt;as described in this post&lt;/a&gt;) then you had to roll your own binder.  With the latest releases of MVC, the DefaultModelBinder that comes OOTB with MVC is now quite robust and is even capable of dealing with those more complex binding scenarios.  Hence, my preferred method for performing the valiation is best described in &lt;a href="http://codebetter.com/blogs/david.hayden/archive/2009/02/03/an-aha-moment-on-mvc-validation-extensibility-in-defaultmodelbinder-bye-to-idataerrorinfo.aspx" target="_blank"&gt;this post by David Hayden here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;However, the one issue with that method is that, although the binder deals well with the complex object, you’ll still run into the same issue with the VAB when it comes to the Key property of the validation messages.  That is, the key is the name of the business object property itself which does not always match the property of the view model.  For example, let’s revisit the example from my previous post and update it to use this new method.  We have our Model passed to our view defined as:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ContactViewData&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Contact Contact { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;State&amp;gt; StateList { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We bind to our textbox like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"Contact.FirstName"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Or, if you prefer the MVC Futures approach, like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBoxFor(m =&amp;gt; m.Contact.FirstName) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So our mismatch is that when the FirstName is invalid, the key for the validation result will be “FirstName” but we were binding to “Contact.FirstName”.  You have two basic options to tackle this type of situation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Option 1 – Prepend appropriate prefix with your binder&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is basically a re-write of my original method by utilizing a custom model binder that derives from the DefaultModelBinder.  This is also a hybrid of Hayden’s approach:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ContactModelBinder : DefaultModelBinder&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        var validator = ValidationFactory.CreateValidator(bindingContext.ModelType);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        var validationResults = validator.Validate(bindingContext.Model);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var result &lt;span class="kwrd"&gt;in&lt;/span&gt; validationResults)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; mvcKey = GetMvcKey(result);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            bindingContext.ModelState.AddModelError(mvcKey, result.Message);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; Dictionary&amp;lt;Type, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; propertyPrefixMap = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;Type, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Contact), &lt;span class="str"&gt;"Contact"&lt;/span&gt; },&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Address), &lt;span class="str"&gt;"Contact.Address"&lt;/span&gt; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    };&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;    &lt;span class="rem"&gt;/// Converts an Enterprise Library ValidationResult into the correct "key" to be used by MVC Views.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name="validationResult"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetMvcKey(ValidationResult validationResult)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; result;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;        propertyPrefixMap.TryGetValue(validationResult.Target.GetType(), &lt;span class="kwrd"&gt;out&lt;/span&gt; result);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(result))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; validationResult.Key;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; result + &lt;span class="str"&gt;"."&lt;/span&gt; + validationResult.Key;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This upside is that you enable you model and validations to match precisely.  The downside is that this model binder does not have a lot of re-use if you’re not using this model in multiple views.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Option 2 – Set your Html.ValidationMessage() differently&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this typical scenario, you’d set up your view like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"Contact.FirstName"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ValidationMessage(&lt;span class="str"&gt;"Contact.FirstName"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Of course, this leads to the issue described above. As an alternative, you could use different name parameters like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"Contact.FirstName"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ValidationMessage(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The upside is that you could leverage a more re-usable binder as described in Hayden’s post.  The downside is that it seems a little counter-intuitive to be using different parameters on the TextBox() and ValiationMessage() extension methods to represent the same business object property.  Perhaps this mis-match “feels” a little better with the MvcFutures syntax:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBoxFor(m =&amp;gt; m.Contact.FirstName) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ValidationMessage(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Whichever way you end up choosing, you certainly have a couple of decent options.  The fact that MVC was designed in such a flexible way to be able to give you these options in the first place speaks volumes.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130144"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130144" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/130144.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/vIMUyeM-xeo" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/03/16/enterprise-library-validation-application-block-with-mvc-binders.aspx</guid>
            <pubDate>Tue, 17 Mar 2009 11:17:22 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/130144.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/03/16/enterprise-library-validation-application-block-with-mvc-binders.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/130144.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/130144.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/03/16/enterprise-library-validation-application-block-with-mvc-binders.aspx</feedburner:origLink></item>
        <item>
            <title>Microsoft Tech Days &amp;ndash; MVC Presentation</title>
            <category>.NET 3.5</category>
            <category>C# 3.0</category>
            <category>MVC</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/25JCtTr-V5I/microsoft-tech-days-ndash-mvc-presentation.aspx</link>
            <description>&lt;p&gt;On April 1 I will be presenting ASP.NET MVC at Microsoft Tech Days.  This is a totally free 24-hour virtual event.  You can register right now at: &lt;a href="http://www.msfttechdays.com/dac/" target="_blank"&gt;http://www.msfttechdays.com&lt;/a&gt;. Hope to see you there!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130083"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130083" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/130083.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/25JCtTr-V5I" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/03/14/microsoft-tech-days-ndash-mvc-presentation.aspx</guid>
            <pubDate>Sat, 14 Mar 2009 12:34:37 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/130083.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/03/14/microsoft-tech-days-ndash-mvc-presentation.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/130083.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/130083.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/03/14/microsoft-tech-days-ndash-mvc-presentation.aspx</feedburner:origLink></item>
        <item>
            <title>Presentation at SOMD NUG &amp;ndash; LINQ to SQL</title>
            <category>LINQ</category>
            <category>C# 3.0</category>
            <category>.NET 3.5</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/udh9n7G7sy4/presentation-at-somd-nug-ndash-linq-to-sql.aspx</link>
            <description>&lt;p&gt;Tomorrow I’ll be giving a presentation at &lt;a href="http://www.somd-dnug.org/" target="_blank"&gt;Southern Maryland .NET User Group&lt;/a&gt; on LINQ to SQL.  Details of the event can be found here:  &lt;a href="http://www.communitymegaphone.com/ShowEvent.aspx?EventID=1022" target="_blank"&gt;http://www.communitymegaphone.com/ShowEvent.aspx?EventID=1022&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129923"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129923" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/129923.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/udh9n7G7sy4" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/03/08/presentation-at-somd-nug-ndash-linq-to-sql.aspx</guid>
            <pubDate>Mon, 09 Mar 2009 08:46:36 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/129923.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/03/08/presentation-at-somd-nug-ndash-linq-to-sql.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/129923.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/129923.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/03/08/presentation-at-somd-nug-ndash-linq-to-sql.aspx</feedburner:origLink></item>
        <item>
            <title>Custom C# 3.0 LINQ Max Extension Method</title>
            <category>.NET 3.5</category>
            <category>C# 3.0</category>
            <category>LINQ</category>
            <link>http://feedproxy.google.com/~r/SteveMichelotti/~3/6OzF3TTxnQw/custom-c-3.0-linq-max-extension-method.aspx</link>
            <description>&lt;p&gt;The System.Core assembly in .NET 3.5 contains the main LINQ methods for dealing with objects such as the &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.max.aspx" target="_blank"&gt;Max() extension method&lt;/a&gt;. Like many of the LINQ extension methods, the Max() method has many overloads that allow you to do things like this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;List&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; list = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; { 1, 2, 17, 14, 21, 4 };&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;"Max: "&lt;/span&gt; + list.Max()); //&amp;lt;- &lt;span class="str"&gt;"Max: 21"&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is all well and good but what if you need to do something a little more interesting?  There are endless examples to think of but for the sake of this discussion, let’s say we have a directory and we want to find the latest/newest file in that directory.  This isn’t very complicated and there are several ways to do it but one simple example might be this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetNewestFileInDirectory(&lt;span class="kwrd"&gt;string&lt;/span&gt; directory)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    FileInfo latestFile = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var fileName &lt;span class="kwrd"&gt;in&lt;/span&gt; Directory.GetFiles(directory))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        FileInfo currentFile = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileInfo(fileName);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (latestFile == &lt;span class="kwrd"&gt;null&lt;/span&gt; || currentFile.LastWriteTimeUtc &amp;gt; latestFile.LastWriteTimeUtc)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            latestFile = currentFile;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; latestFile.Name;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For each file in the directory, we’re comparing the last write time and, if it’s greater than any other file timestamp, we store it in the temporary latestFile variable which will eventually be returned.  But wouldn’t it be nicer to be able to use some sort of Max() method in this scenario where we’re considering that the “max” is based on the file’s timestamp?  The FileInfo object doesn’t support any type of IComparable interface so that’s no help – and even if it did, it wouldn’t be much help because there’s no clear idea what it would be based on (e.g., file size? file name? file date?).&lt;/p&gt;

&lt;p&gt;Let’s first see what we can do with the OOB Max() extension method. We could do something like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;IEnumerable&amp;lt;FileInfo&amp;gt; fileList = Directory.GetFiles(directory).Select(f =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FileInfo(f));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;var result = fileList.Max(f =&amp;gt; f.LastAccessTimeUtc);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;"Result is: "&lt;/span&gt; + result); &lt;span class="rem"&gt;//&amp;lt;- "Result is: Result is: 2/6/2009 8:10:54 PM"&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice on line 1 I’m creating an IEnumerable&amp;lt;FileInfo&amp;gt; in a single line of code by leveraging the &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.select.aspx" target="_blank"&gt;Select() extension method&lt;/a&gt;. The Directory.GetFiles() method just returns an array of strings, but I need a collection of the actual FileInfo objects so i can get at the file properties.  Being able to do this on 1 line of code is much more succinct than having to instantiate and object, loop over the source, and continually call the Add() method of the collection.&lt;/p&gt;

&lt;p&gt;Line 2 gives of the Max date which is, in fact, the latest date that we’re looking for.  However, the problem is that I am trying to get the *actual* file that is the latest – just knowing the latest date by itself doesn’t do me a whole lot of good. What I really want to be able to do is the have a Max() method that will determine a “max” of any arbitrary object based on a simple expression that I can specify on-demand. In other words, I want to be able to write the code above but have the result be of type FileInfo so that I can get a reference to the actual FileInfo object that happens to have the maximum date in my collection. This can be done by writing your own customized extension method in roughly a dozen lines of code like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; T Max&amp;lt;T, TCompare&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; collection, Func&amp;lt;T, TCompare&amp;gt; func) &lt;span class="kwrd"&gt;where&lt;/span&gt; TCompare : IComparable&amp;lt;TCompare&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    T maxItem = &lt;span class="kwrd"&gt;default&lt;/span&gt;(T);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    TCompare maxValue = &lt;span class="kwrd"&gt;default&lt;/span&gt;(TCompare);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        TCompare temp = func(item);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (maxItem == &lt;span class="kwrd"&gt;null&lt;/span&gt; || temp.CompareTo(maxValue) &amp;gt; 0)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            maxValue = temp;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            maxItem = item;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; maxItem;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This extension method has 2 generic type arguments. The first – T – in this case will be the FileInfo object. The second – TCompare – in this case will be the DateTime representing the result of the LastAccessTimeUtc property. In order to make this work correctly, you must have the “where TCompare : IComparable&amp;lt;TCompare&amp;gt;” generic constraint to ensure that whatever value specified implements IComparable. The rest of the algorithm is pretty similar conceptually to the original code.&lt;/p&gt;

&lt;p&gt;Now you have a Max() extension method that can be generalized to limitless scenarios. Do you want to find the file with maximum size? Maximum name (alphabetically)? Maximum creation timestamp? Instead of a FileInfo object, you could use it against a collection of Person objects to find the person with the max age or max last name or max date of birth or max date hired, etc., etc. You could also do the same thing for other extension methods (e.g., Min(), etc.).&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129259"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129259" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/129259.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/SteveMichelotti/~4/6OzF3TTxnQw" height="1" width="1"/&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid isPermaLink="false">http://geekswithblogs.net/michelotti/archive/2009/02/06/custom-c-3.0-linq-max-extension-method.aspx</guid>
            <pubDate>Sat, 07 Feb 2009 09:48:58 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/129259.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/02/06/custom-c-3.0-linq-max-extension-method.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/129259.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/129259.aspx</trackback:ping>
        <feedburner:origLink>http://geekswithblogs.net/michelotti/archive/2009/02/06/custom-c-3.0-linq-max-extension-method.aspx</feedburner:origLink></item>
    </channel>
</rss>
