<?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:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Rick Strahl's Web Log</title>
    <link>http://www.west-wind.com/weblog/</link>
    <description>Life, Surf, Code and everything in between</description>
    <generator>West Wind Web Log</generator>
    <language>en-us</language>
    <image>
      <url>http://www.west-wind.com/weblog/images/WebLogBannerLogo.jpg</url>
      <title>Rick Strahl's Web Log</title>
      <link>http://www.west-wind.com/weblog/</link>
    </image>
    <pubDate>Tue, 10 Nov 2009 00:54:27 GMT</pubDate>
    <lastBuildDate>Mon, 09 Nov 2009 08:20:25 GMT</lastBuildDate>
    <geo:lat>20.906999</geo:lat><geo:long>-156.382029</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><meta xmlns="http://pipes.yahoo.com" name="pipes" content="noprocess" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/RickStrahl" type="application/rss+xml" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FRickStrahl" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>$.fadeTo/fadeOut() operations on Table Rows in IE fail</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/AsNk-dxBt30/68055.aspx</link>
      <guid isPermaLink="false">68055_200911090820</guid>
      <pubDate>Mon, 09 Nov 2009 08:20:25 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/68055.aspx#Comments</comments>
      <slash:comments>7</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=68055</wfw:commentRss>
      <category>jQuery</category>
      <description>&lt;p&gt;Here’s a a small problem that one of customers ran into a few days ago: He was playing around with some of the sample code I’ve put out for one of my simple jQuery demos which deals with providing a simple pulse behavior plug-in:&lt;/p&gt;  &lt;pre class="code"&gt;$.fn.pulse = &lt;span style="color: blue"&gt;function&lt;/span&gt;(time) {
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!time)
        time = 2000;

    &lt;span style="color: green"&gt;// *** this == jQuery object that contains selections
    &lt;/span&gt;$(&lt;span style="color: blue"&gt;this&lt;/span&gt;).fadeTo(time, 0.20,
                        &lt;span style="color: blue"&gt;function&lt;/span&gt;() {                    
                            $(&lt;span style="color: blue"&gt;this&lt;/span&gt;).fadeTo(time, 1);
                        });

    &lt;span style="color: blue"&gt;return this&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;it’s a very simplistic plug-in and it works fine for simple pulse animations. However he ran into a problem where it didn’t work when working with tables – specifically pulsing a table row in Internet Explorer. Works fine in FireFox and Chrome, but IE not so much. It also works just fine in IE as long as you don’t try it on tables or table rows specifically. Applying against something like this (an ASP.NET GridView):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;sel =
    $(&lt;span style="color: teal"&gt;&amp;quot;#gdEntries&amp;gt;tbody&amp;gt;tr&amp;quot;&lt;/span&gt;)
            .not(&lt;span style="color: teal"&gt;&amp;quot;:first-child&amp;quot;&lt;/span&gt;)  &lt;span style="color: green"&gt;// no header
            &lt;/span&gt;.not(&lt;span style="color: teal"&gt;&amp;quot;:last-child&amp;quot;&lt;/span&gt;)   &lt;span style="color: green"&gt;// no footer
            &lt;/span&gt;.filter(&lt;span style="color: teal"&gt;&amp;quot;:even&amp;quot;&lt;/span&gt;)
            .addClass(&lt;span style="color: teal"&gt;&amp;quot;gridalternate&amp;quot;&lt;/span&gt;);

&lt;span style="color: green"&gt;// *** Demonstrate simple plugin
&lt;/span&gt;sel.pulse(2000);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;fails in IE. No pulsing happens in any version of IE. After some additional experimentation with single rows and various ways of selecting each and still failing, I’ve come to the conclusion that the various fade operations in jQuery simply won’t work correctly in IE (any version). So even something as ‘elemental’ as this:&lt;/p&gt;

&lt;pre class="code"&gt;var el = $(&lt;span style="color: teal"&gt;&amp;quot;#gdEntries&amp;gt;tbody&amp;gt;tr&amp;quot;&lt;/span&gt;).&lt;span style="color: blue"&gt;get&lt;/span&gt;(0);&lt;br /&gt;$(el).fadeOut(2000);&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;is not working correctly. The item will stick around for 2 seconds and then magically disappear.&lt;/p&gt;

&lt;p&gt;Likewise:&lt;/p&gt;

&lt;pre class="code"&gt;sel.hide().fadeIn(5000);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;also doesn’t fade in although the items become &lt;em&gt;immediately&lt;/em&gt; visible in IE. Go figure that behavior out.&lt;/p&gt;

&lt;p&gt;Thanks to a &lt;a href="http://twitter.com/red_square/status/5552944885" target="_blank"&gt;tweet from red_square&lt;/a&gt; and a link he provided here is a grid that explains what works and doesn’t in IE (and most last gen browsers) regarding opacity:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.quirksmode.org/js/opacity.html" href="http://www.quirksmode.org/js/opacity.html"&gt;http://www.quirksmode.org/js/opacity.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It appears from this link that table and row elements can’t be made opaque, but td elements can. This means for the row selections I can force each of the td elements to be selected and then pulse all of those. Once you have the rows it’s easy to explicitly select all the columns in those rows with .find(“td”). Aha the following actually works:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;sel =
    $(&lt;span style="color: teal"&gt;&amp;quot;#gdEntries&amp;gt;tbody&amp;gt;tr&amp;quot;&lt;/span&gt;)
            .not(&lt;span style="color: teal"&gt;&amp;quot;:first-child&amp;quot;&lt;/span&gt;)  &lt;span style="color: green"&gt;// no header
            &lt;/span&gt;.not(&lt;span style="color: teal"&gt;&amp;quot;:last-child&amp;quot;&lt;/span&gt;)   &lt;span style="color: green"&gt;// no footer
            &lt;/span&gt;.filter(&lt;span style="color: teal"&gt;&amp;quot;:even&amp;quot;&lt;/span&gt;)
            .addClass(&lt;span style="color: teal"&gt;&amp;quot;gridalternate&amp;quot;&lt;/span&gt;);

&lt;span style="color: green"&gt;// *** Demonstrate simple plugin
&lt;/span&gt;sel.find(&lt;span style="color: teal"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;).pulse(2000); &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;A little unintuitive that, but it works.&lt;/p&gt;

&lt;h3&gt;Stay away from &amp;lt;table&amp;gt; and &amp;lt;tr&amp;gt; Fades&lt;/h3&gt;

&lt;p&gt;The moral of the story is – stay away from TR, TH and TABLE fades and opacity. If you have to do it on tables use the columns instead and if necessary use .find(“td”) on your row(s) selector to grab all the columns.&lt;/p&gt;

&lt;p&gt;I’ve been surprised by this uhm relevation, since I use fadeOut in almost every one of my applications for deletion of items and row deletions from grids are not uncommon especially in older apps. But it turns out that fadeOut actually works in terms of behavior: It removes the item when the timeout’s done and because the fade is relatively short lived and I don’t extensively test IE code any more I just never noticed that the fade wasn’t happening.&lt;/p&gt;

&lt;p&gt;Note – this behavior or rather lack thereof appears to be specific to table table,tr,th elements. I see no problems with other elements like &amp;lt;div&amp;gt; and &amp;lt;li&amp;gt; items.&lt;/p&gt;

&lt;p&gt;Chalk this one up to another of IE’s shortcomings.&lt;/p&gt;

&lt;p&gt;Incidentally I’m not the only one who has failed to address this in my simplistic plug-in: The jquery-ui pulsate effect also fails on the table rows in the same way.&lt;/p&gt;

&lt;pre class="code"&gt;sel.effect(&lt;span style="color: teal"&gt;&amp;quot;pulsate&amp;quot;&lt;/span&gt;, { times: 3 }, 2000);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;and it also works with the same workaround. If you’re already using jquery-ui definitely use this version of the plugin which provides a few more options…&lt;/p&gt;

&lt;p&gt;Bottom line: be careful with table based fade operations and remember that if you do need to fade – fade on columns.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=jQuery'&gt;jQuery&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f68055.aspx&amp;title=%24.fadeTo%2ffadeOut()+operations+on+Table+Rows+in+IE+fail"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f68055.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;p&gt;&lt;a href='http://west-wind.com/Weblog/wwBanner.ashx?a=c&amp;id=e47b9595&amp;t=633934112673485215' target='_top'&gt;&lt;img src='http://www.west-wind.com/banners/wwstore_small.gif' border='0'&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AsNk-dxBt30:eTpRdEuq5u4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AsNk-dxBt30:eTpRdEuq5u4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AsNk-dxBt30:eTpRdEuq5u4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=AsNk-dxBt30:eTpRdEuq5u4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AsNk-dxBt30:eTpRdEuq5u4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=AsNk-dxBt30:eTpRdEuq5u4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AsNk-dxBt30:eTpRdEuq5u4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=AsNk-dxBt30:eTpRdEuq5u4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AsNk-dxBt30:eTpRdEuq5u4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/AsNk-dxBt30" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/68055.aspx</feedburner:origLink></item>
    <item>
      <title>ClientIDMode in ASP.NET 4.0</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/C5bcs5HHyj8/54760.aspx</link>
      <guid isPermaLink="false">54760_200911072358</guid>
      <pubDate>Sat, 07 Nov 2009 23:58:03 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/54760.aspx#Comments</comments>
      <slash:comments>16</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=54760</wfw:commentRss>
      <category> ASP.NET</category>
      <category>JavaScript</category>
      <description>&lt;p&gt;One of the more anticipated features of ASP.NET 4.0 – at least for me - is the new ClientIDMode property, which can be used to force controls to generate clean Client IDs that don’t follow ASP.NET’s munged NamingContainer ID conventions. To be clear, NamingContainer IDs are necessary for complex controls and pages that nest many things inside of a single context, but for most application level Web design scenarios those munged IDs get in the way and don’t provide a lot of value.&lt;/p&gt;  &lt;p&gt;The munged IDs affect all sorts of development scenarios from design and CSS styling where ID haven’t been predictable for #id styling:&lt;/p&gt;  &lt;pre class="code"&gt;#ctl00_content_txtName 
{
    font-weight: bold;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;vs the more expected:&lt;/p&gt;

&lt;pre class="code"&gt;#txtName
{
    font-weight: bold;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And even more so there’s the whole nightmare of &lt;a href="http://www.west-wind.com/Weblog/posts/42319.aspx" target="_blank"&gt;ClientIds in script pages&lt;/a&gt; where code like this:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
        var &lt;/span&gt;txtName = $(&lt;span style="color: maroon"&gt;&amp;quot;&lt;/span&gt;&lt;span style="background: yellow; color: maroon; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: maroon"&gt;= txtName.ClientID &lt;/span&gt;&lt;span style="background: yellow; color: maroon; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: maroon"&gt;&amp;quot;&lt;/span&gt;);
        &lt;span style="color: blue"&gt;var &lt;/span&gt;txtTitle = $(&lt;span style="color: maroon"&gt;&amp;quot;[id$=_txtTitle]&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;or some other pre-generation code is necessary to get client id’s properly referenced in script code.&lt;/p&gt;

&lt;h3&gt;ClientIDMode &lt;/h3&gt;

&lt;p&gt;In prior versions of ASP.NET you had to live with the problem or work around with various hacks. In ASP.NET 4.0 things get a little easier via the new ClientIDMode property which allows you to specify exactly how a ClientID is generated.&lt;/p&gt;

&lt;p&gt;The idea is simple: you get a new ClientIDMode property on all ASP.NET controls which can be set either at the actual control or somewhere up the NamingContainer chain. If the ClientIDMode property is not set on a control it inherits the setting from the nearest NamingContainer with the exception of&amp;#160; the &lt;strong&gt;&amp;lt;asp:Content&amp;gt;&lt;/strong&gt; placeholder which doesn’t participate in ClientIDMode processing (bummer!).&lt;/p&gt;

&lt;p&gt;This means if you choose to you can set ClientIDMode on the Page level and it will trickle down into all the child controls on the page, but a custom naming container like a User Control can still override the ClientIDMode to enforce it’s naming container requirements. It’ll be interesting to see how much existing code might break based on this inheritance scheme as custom controls may lose controls over their ClientID naming if the ClientIDMode property isn’t set explicitly.&lt;/p&gt;

&lt;p&gt;Anyway let’s take a look at a very simple example and how the ClientIDMode property affects the ID rendering. Imagine you have a page that uses a master page and is set up like this: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;font face="Courier New"&gt;&lt;span style="background: yellow; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@&lt;/span&gt;&lt;span style="color: maroon"&gt;Page&lt;/span&gt;&lt;span style="color: red"&gt;Title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;MasterPageFile&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;~/Site.Master&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;AutoEventWireup&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot; 
      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: red"&gt;CodeBehind&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;=&amp;quot;WebForm2.aspx.cs&amp;quot; 
      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: red"&gt;Inherits&lt;/span&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font face="Courier New"&gt;=&amp;quot;WebApplication1.WebForm2&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;&lt;span style="color: red"&gt;ClientIDMode&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Predictable&amp;quot;&lt;/span&gt; 

        &lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/span&gt;&lt;font face="Courier New"&gt;&lt;span style="background: yellow; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;%&amp;gt; 
      &lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Content&lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;ContentPlaceHolderID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;ClientIDMode&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;=&amp;quot;Static&amp;quot; &amp;gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;TextBox &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;txtName&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Static&amp;quot;&lt;/strong&gt; /&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Content&lt;/span&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font face="Courier New"&gt;&amp;gt;&lt;/font&gt; 

    &lt;br /&gt;&lt;/span&gt;

  &lt;br /&gt;Here’s what the various values for the txtName property can look like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AutoID&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the existing behavior in ASP.NET 1.x-3.x where full naming container munging takes place. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$content$txtName&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00_content_txtName&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In Beta 2 this is the default value for the Page. According to the latest VS 2010 documentation however, the default behavior by release time will be Predictable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static 
    &lt;br /&gt;&lt;/strong&gt;This option forces the control’s ClientID to use its ID value directly. No naming container naming at all is applied and you end up with clean client ids:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input&lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$content$txtName&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;/font&gt;&lt;span style="color: blue"&gt;&lt;font face="Courier New"&gt;=&amp;quot;txtName&amp;quot; /&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This option is what most of us &lt;strong&gt;want&lt;/strong&gt; to use, but you have to be clear on that this can potentially cause conflicts with other control on the page. If there are several instances of the same naming container (several instances of the same user control for example) there can easily be a client ID naming conflict. It’s basically up to you to decide whether this is a problem or not. &lt;/p&gt;

&lt;p&gt;Note that if you assign Static to a Databound control like a list child controls in templates do not get unique IDs either, so for list controls where you rely on unique Id for child controls you’ll probably want to use Predictable rather than Static. More on this a little later when I discuss ClientIDRowSuffix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Predictable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The previous two values are pretty self-explanatory. Predictable however, requires some explanation. To me at least it's not in the least bit predictable :-}. 
  &lt;br /&gt;MSDN defines this enum value as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This algorithm is used for controls that are in data-bound controls. The &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientid%28VS.100%29.aspx"&gt;ClientID&lt;/a&gt; value is generated by concatenating the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientid%28VS.100%29.aspx"&gt;ClientID&lt;/a&gt; value of the parent naming container with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.id%28VS.100%29.aspx"&gt;ID&lt;/a&gt; value of the control. If the control is a data-bound control that generates multiple rows, the value of the data field specified in the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.idataboundlistcontrol.clientidrowsuffix%28VS.100%29.aspx"&gt;ClientIDRowSuffix&lt;/a&gt; property is added at the end. For the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview%28VS.100%29.aspx"&gt;GridView&lt;/a&gt; control, multiple data fields can be specified. If the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.idataboundlistcontrol.clientidrowsuffix%28VS.100%29.aspx"&gt;ClientIDRowSuffix&lt;/a&gt; property is blank, a sequential number is added at the end instead of a data-field value. Each segment is separated by an underscore character (_).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key that makes this value a bit confusing is that it relies on the parent NamingContainer’s ClientID to build it’s own client ID value. Which effectively means that the value is not predictable at all but rather very tightly coupled to the parent naming container’s ClientIDMode setting. &lt;/p&gt;

&lt;p&gt;For our simple textbox example, if the ClientIDMode property of the parent naming container (Page in this case) is set to “Predictable” you’ll get this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$content$txtName&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;content_txtName&amp;quot;&lt;/strong&gt; /&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;which gives a name that walk up to the currently active naming container (the MasterPage content container) and starts the name from there downward. Think of this as a semi unique name that’s guaranteed unique only for the naming container. 
  &lt;br /&gt;

  &lt;br /&gt;If on the other hand the Page is set to “AutoID” you get with Predicable on txtName:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$content$txtName&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;ctl00_content_txtName&amp;quot;&lt;/strong&gt; /&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The latter is effectively the same as if you specified AutoID in this scenario because it inherits the AutoID naming from the Page and Content control of the page.&amp;#160; But again – predictable behavior always depends on the parent naming container and how it generates its id so the ID may not always be exactly the same as the AutoID generated value because somewhere in the NamingContainer chain the ClientIDMode setting may be set to a different value. For example if you had another naming container in the middle that was set to Static you’d end up effectively with an ID that starts with the NamingContainers' ID rather than the whole ctl000_content munging.&lt;/p&gt;

&lt;p&gt;The most common use however for Predictable will be for DataBound controls, which results in a each data bound item to get a unique ClientID. &lt;/p&gt;

&lt;p&gt;Predictable is useful, but only if all naming containers down the chain use this setting. Otherwise you’re right back to the munged Ids that are pretty unpredictable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inherit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The final setting is Inherit which is the default for all controls except Page (AFAIK). This means that controls by default inherit the naming container’s ClientIDMode setting.&lt;/p&gt;

&lt;h3&gt;Inheritance&lt;/h3&gt;

&lt;p&gt;The explicit values are pretty obvious in what they do and when they are applied to individual controls. AutoID is classic behavior, Static is what we want in typical client centric apps, and Predictable is what you typically will want to use for list controls and anything that has possible naming conflicts. &lt;/p&gt;

&lt;p&gt;Things get a little more tricky with inheritance of these settings. Specicfically the ClientIDMode property inherits from a &lt;strong&gt;NamingContainer&lt;/strong&gt; down. Unlike most other ASP.NET hierarchy inheritance the ClientIDMode inheritance is based on the NamingContainer not on the Parent Container.&lt;/p&gt;

&lt;p&gt;What this means is that if you set ClientIDMode=&amp;quot;Static&amp;quot; on a Page or MasterPage all controls inherit that settings:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: yellow; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: maroon"&gt;Page &lt;/span&gt;&lt;span style="color: red"&gt;Title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;MasterPageFile&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;~/Site.Master&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;AutoEventWireup&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;         &lt;/span&gt;&lt;span style="color: red"&gt;CodeBehind&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;WebForm2.aspx.cs&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Inherits&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;WebApplication1.WebForm2&amp;quot;  &lt;br /&gt;         &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Static&amp;quot;&lt;/strong&gt; &lt;/span&gt;&lt;span style="background: yellow; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;%&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;If you don’t set the ClientIDMode on any other controls the entire page will use Static. Any UserControls can override the setting but all controls will use this setting.&lt;/p&gt;

&lt;p&gt;Now imagine I do:&lt;/p&gt;
&lt;font face="Courier New"&gt;&lt;span style="background: yellow; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: maroon"&gt;Page &lt;/span&gt;&lt;span style="color: red"&gt;Title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;MasterPageFile&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;~/Site.Master&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;AutoEventWireup&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot; 
    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;/span&gt;&lt;span style="color: red"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CodeBehind&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;WebForm2.aspx.cs&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Inherits&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;=&amp;quot;WebApplication1.WebForm2&amp;quot; 
    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Predictable&amp;quot;&lt;/strong&gt; &lt;/span&gt;&lt;/font&gt;&lt;span style="background: yellow; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;&lt;font face="Courier New"&gt;%&amp;gt;&lt;/font&gt; &lt;/span&gt;

&lt;p&gt;and I’m running inside of a master page and I put in a block of controls like this:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Panel &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;  &lt;/span&gt;&lt;span style="color: red"&gt;ClientIDMode&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Static&amp;quot;&amp;gt;
        &lt;/span&gt;This is a test:
        &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;TextBox &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;txtName&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt; /&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Button &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btnSubmit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Go&amp;quot; &lt;/span&gt;&lt;span style="color: blue"&gt; /&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Panel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;Quick what should you see? Unfortunately not what I would have expected – although it’s true to what the documentation advertises. The block above renders into:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;This is a test:
    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$content$txtName&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;content_txtName&amp;quot;&lt;/strong&gt; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;submit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$content$btnSubmit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Go&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;content_btnSubmit&amp;quot;&lt;/strong&gt; /&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;What’s happening here is that even though we specified Static naming on the Panel (which is &lt;strong&gt;not&lt;/strong&gt; a NamingContainer) Predictable naming is used which runs up to the nearest naming container – in this case the Master Page Content control and using that as its base for the name. If I want those controls to render with clean ids I need to explicitly mark the controls to use Static:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Panel &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;  &lt;/span&gt;&lt;span style="color: red"&gt;ClientIDMode&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Static&amp;quot;&amp;gt;
        &lt;/span&gt;This is a test:
        &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;TextBox &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;txtName&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Static&amp;quot;&lt;/strong&gt; /&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Button &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btnSubmit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Go&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Static&amp;quot;&lt;/strong&gt; /&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Panel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;or by changing the Page’s ClientIDMode to Static:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: yellow; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@ &lt;/span&gt;&lt;span style="color: maroon"&gt;Page &lt;/span&gt;&lt;span style="color: red"&gt;Title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;MasterPageFile&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;~/Site.Master&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;AutoEventWireup&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot; 
        &lt;/span&gt;&lt;span style="color: red"&gt;CodeBehind&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;WebForm2.aspx.cs&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Inherits&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;WebApplication1.WebForm2&amp;quot;  &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Static&amp;quot;&lt;/strong&gt; &lt;/span&gt;&lt;span style="background: yellow; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous"&gt;%&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;With either of those in place I now get:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Panel1&amp;quot;&amp;gt;
        &lt;/span&gt;This is a test:
        &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$content$txtName&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtName&amp;quot;&lt;/strong&gt; /&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;submit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$content$btnSubmit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Go&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;btnSubmit&amp;quot;&lt;/strong&gt; /&amp;gt;    
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Notice that when page level ClientIDMode=&amp;quot;Static&amp;quot; the &amp;lt;div&amp;gt; tag now renders with an explicit ID which is rather inconsistent (it’s not there if I just have ClientIDMode=”Static” on the Panel alone).&lt;/p&gt;

&lt;p&gt;Note that you unfortunately &lt;strong&gt;cannot&lt;/strong&gt; use an &amp;lt;asp:Content&amp;gt; control and specify the ClientIDMode like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Content &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;content&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ContentPlaceHolderID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;content&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Static&amp;quot;&lt;/strong&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This has no effect&amp;#160; on the controls contained inside of the Content container which still inherit the ClientIDMode from Page in this case. This is really annoying because the Content container certainly is part of the naming container hierarchy that is reflected in the ClientIDName for Predictable and AutoId.&lt;/p&gt;

&lt;p&gt;There’s a way around this by using:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Static on the List Control&lt;/li&gt;

  &lt;li&gt;Predictable on all of the Child controls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;GridView &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;gvProducts&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;false&amp;quot;
                  &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Static&amp;quot; &lt;span style="color: red"&gt;ClientIDRowSuffix&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;id&amp;quot;&lt;/strong&gt; &lt;/span&gt; 
                  &lt;/span&gt;&lt;span style="color: red"&gt;DataSourceID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;xmlDataSource&amp;quot; 
                   &amp;gt;  
                  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;Columns&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;TemplateField&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; 
                        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Label &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;txtTitle&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;='&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;Eval(&amp;quot;title&amp;quot;) &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;' &lt;br /&gt;                                       &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Predictable&amp;quot;&lt;/strong&gt;/&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;TemplateField&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;TemplateField&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; 
                        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;Label &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;txtId&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;='&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;Eval(&amp;quot;id&amp;quot;) &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;' &lt;br /&gt;                                   &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;ClientIDMode&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;Predictable&amp;quot;&lt;/strong&gt; /&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;TemplateField&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

                  &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;Columns&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;  
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;GridView&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;which results in:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;table &lt;/span&gt;&lt;span style="color: red"&gt;cellspacing&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;rules&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;all&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;border&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Table2&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;border-collapse&lt;/span&gt;&lt;span style="color: blue"&gt;:collapse;&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;th &lt;/span&gt;&lt;span style="color: red"&gt;scope&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;col&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;nbsp;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;th&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;th &lt;/span&gt;&lt;span style="color: red"&gt;scope&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;col&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;nbsp;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;th&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtTitle_32&amp;quot;&lt;/strong&gt;&amp;gt;&lt;/span&gt;West Wind &lt;a href="http://www.west-wind.com/westwindwebtoolkit/" target="WebToolkit"&gt;West Wind Web Toolkit&lt;/a&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtId_32&amp;quot;&lt;/strong&gt;&amp;gt;&lt;/span&gt;32&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;table&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; 
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This does produce what I would consider a desirable result although I had hoped that using Static on the list control without any further formatting would have produced this result. Unfortunately the Predictable setting on each of the child controls is required to get the clean ids into the child controls.&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;ClientIDRowSuffix&lt;/h3&gt;

&lt;p&gt;Another feature of the ClientID improvements in ASP.NET 4.0 is the ClientIDRowSuffix which can be applied to DataBound/List controls. I used it above in the grid to have the enumerated client id of the child controls use the value of an &lt;em&gt;Id &lt;/em&gt;field from the database as the enumeration value. This setting basically determines how ID values for template controls in databound controls are generated, but it &lt;strong&gt;requires &lt;/strong&gt;that the ClientIDMode is set to &lt;em&gt;Predictable&lt;/em&gt;. It produces:&lt;/p&gt;

&lt;p&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtTitle_32&amp;quot;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where the _32 in this case comes from the Id of the data source which is nice than only using sequentially numbered values in previous versions of ASP.NET which were often worthless in client situations. Using an actual data value that can be looked retrieved on the client and sent back on an Ajax callback makes these IDs much more useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wouldn’t it be nice if Client Row Ids could be generated?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What would be even nicer is that the generated ‘rows’ of a data bound control could optionally generate ids. In most Ajax situations the row level ID is really what’s useful – selections of rows for deletion, editing and updating always require an ID even if there are no child controls, but ASP.NET doesn’t provide an easy mechanism for embedding row ids. It sure would be get output like this:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;content_gvProducts_33&amp;quot;&amp;gt;
        &lt;/span&gt;...
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This can be done with code in a GridView (and other list controls) with ItemCreated events it’s quite a pain to do this. For example for the gridview I’m using with a simple XmlDataSource control I have to do this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;protected void &lt;/span&gt;gvProducts_RowCreated(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: rgb(43,145,175)"&gt;GridViewRowEventArgs &lt;/span&gt;e)
{
    &lt;span style="color: blue"&gt;object &lt;/span&gt;dataItem = e.Row.DataItem;

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(dataItem != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color: rgb(43,145,175)"&gt;XPathNavigator &lt;/span&gt;nav = ((&lt;span style="color: rgb(43,145,175)"&gt;IXPathNavigable&lt;/span&gt;)dataItem).CreateNavigator();
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(nav != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            e.Row.Attributes.Add(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.gvProducts.ID + &lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;_&amp;quot; &lt;/span&gt;+ nav.GetAttribute(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;,&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;&amp;quot;&lt;/span&gt;));
    }
}&lt;/pre&gt;

&lt;p&gt;to produce output like this:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;gvProducts_33&amp;quot;&amp;gt; &lt;/span&gt;... &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;which is anything but intuitive for such a common scenario (although this IS a bit easier to grab the data if you use Entity list or DataTable binding).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data List Controls and Static Produces Invalid HTML&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One more note: Using &lt;em&gt;Static&lt;/em&gt; on list controls with child controls and NOT using &lt;em&gt;Predictable&lt;/em&gt; for child controls is problematic as it will generate static IDs for ALL template items:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;table &lt;/span&gt;&lt;span style="color: red"&gt;cellspacing&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;0&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;rules&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;all&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;border&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Table1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;border-collapse&lt;/span&gt;&lt;span style="color: blue"&gt;:collapse;&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;th &lt;/span&gt;&lt;span style="color: red"&gt;scope&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;col&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;nbsp;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;th&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;th &lt;/span&gt;&lt;span style="color: red"&gt;scope&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;col&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;nbsp;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;th&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtTitle&amp;quot;&lt;/strong&gt;&amp;gt;&lt;/span&gt;West Wind &lt;a href="http://www.west-wind.com/westwindwebtoolkit/" target="WebToolkit"&gt;West Wind Web Toolkit&lt;/a&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtId&amp;quot;&lt;/strong&gt;&amp;gt;&lt;/span&gt;32&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                            &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtTitle&amp;quot;&lt;/strong&gt;&amp;gt;&lt;/span&gt;West Wind &lt;a href='http://www.west-wind.com/westwindwebstore/' target="WebStore"&gt;West Wind Web Store&lt;/a&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtId&amp;quot;&lt;/strong&gt;&amp;gt;&lt;/span&gt;33&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;table&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This is invalid HTML since there are multiple controls with the same id attribute on the page which is clearly undesirable. To fix this remember to use Predictable on any of the child controls.&lt;/p&gt;

&lt;p&gt;Or better yet stay away from server controls altogether in template columns – stick to plain HTML controls and use AJAX to update values to the server more interactively. :-}&lt;/p&gt;

&lt;h3&gt;How should we use ClientIDMode?&lt;/h3&gt;

&lt;p&gt;I suspect it’s going to take some time to figure out all the little nuances of the new ClientIDMode features. At the very least the Static option on individual controls allows you to explicitly force controls to use the name you want it to and that’s a win any way you look at it.&lt;/p&gt;

&lt;p&gt;For now I think the following is what I want to use in typical page scenarios in my applications:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add ClientIDMode=&amp;quot;Static&amp;quot; to each Page&amp;#160; (or in web.config’s &amp;lt;pages&amp;gt; setting) &lt;/li&gt;

  &lt;li&gt;Add ClientIDMode=&amp;quot;Predictable&amp;quot; explicitly to each List Control Children in Databound Template&lt;/li&gt;

  &lt;li&gt;Override explicitly to Predictable where naming conflicts are a problem and to AutoId for the extreme edge case&lt;/li&gt;

  &lt;li&gt;For Control Development leave at default behavior if possible (ie. Inherit from parent) &lt;/li&gt;

  &lt;li&gt;Override only when necessary and preferrably on individual subcontrols &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also for now I think it’s a good idea to EXPLICITLY specify a ClientIDMode on each page (or in your project) or explicitly declare the value in your web.config file:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;pages &lt;/span&gt;&lt;span style="color: red"&gt;clientIDMode&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Static&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;to ensure you get a predictable setting since the current Beta 2 implementation and the documentation are at odds of what the default value actually is.&lt;/p&gt;

&lt;p&gt;It’s funny to think that such simple functionality should cause such complex workarounds and dependent behaviors but I suspect with a consistent regimen of CLientIDMode settings you can achieve output that works for any scenario. Time will tell.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category= ASP.NET'&gt; ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=JavaScript'&gt;JavaScript&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f54760.aspx&amp;title=ClientIDMode+in+ASP.NET+4.0"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f54760.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;p&gt;&lt;a href='http://west-wind.com/Weblog/wwBanner.ashx?a=c&amp;id=e47b9595&amp;t=633934112673495215' target='_top'&gt;&lt;img src='http://www.west-wind.com/banners/wwstore_small.gif' border='0'&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=C5bcs5HHyj8:5SXgWiCEE_c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=C5bcs5HHyj8:5SXgWiCEE_c:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=C5bcs5HHyj8:5SXgWiCEE_c:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=C5bcs5HHyj8:5SXgWiCEE_c:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=C5bcs5HHyj8:5SXgWiCEE_c:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=C5bcs5HHyj8:5SXgWiCEE_c:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=C5bcs5HHyj8:5SXgWiCEE_c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=C5bcs5HHyj8:5SXgWiCEE_c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=C5bcs5HHyj8:5SXgWiCEE_c:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/C5bcs5HHyj8" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/54760.aspx</feedburner:origLink></item>
    <item>
      <title>Ambiguous References in DefaultWsdlHelpGenerator.aspx</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/VWiG7-lT0JM/61923.aspx</link>
      <guid isPermaLink="false">61923_200911030152</guid>
      <pubDate>Tue, 03 Nov 2009 01:52:22 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/61923.aspx#Comments</comments>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=61923</wfw:commentRss>
      <category>ASP.NET</category>
      <category>Web Services</category>
      <description>&lt;p&gt;Here’s a little oddball issue I ran into today that hosed – during a demo of course – all the existing ASMX Web Services text pages in one of my applications. The error that occurred resulted in a yellow screen of death when accessing the ASMX service directly (http://localhost/wwstore/services/WebStoreConsumerService.asmx):&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;CS0104: 'DataBinder' is an ambiguous reference between 'Westwind.Web.Controls.DataBinder' and 'System.Web.UI.DataBinder'&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="border: 0px none ; display: inline;" title="WsdlPageerror" alt="WsdlPageerror" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/AmbiguousReferencesinDefaultWsdlHel.aspx_11520/WsdlPageerror_d5b88899-c749-4390-af36-341eac308270.png" width="796" border="0" height="600"&gt; &lt;/p&gt;  &lt;p&gt;The issue here is caused by the fact that I have&amp;nbsp; a component in &lt;a href="http://www.west-wind.com/WestwindWebToolkit/docs?page=_1v51f7d88.htm" target="_blank"&gt;Westwind.Web.Controls.DataBinder&lt;/a&gt; that apparently conflicts with the System.Web.UI.DataBinder. You would think that the separate namespaces should isolate me from problems like this, but unfortunately here the overlapping names ram heads due to the use of a static method call of DataBinder.Eval(). &lt;/p&gt;  &lt;p&gt;The problem is that the DataBinder.Eval() is a static method call so there’s never an instance created to qualify exactly which type is to be used. Both System.Web.UI and Westwind.Web.Controls are in scope, the former because it’s automatically included as a namespace, the latter because it’s added explicitly in the &amp;lt;pages&amp;gt;&amp;lt;namespaces&amp;gt; section of Web.Config:&lt;/p&gt;  &lt;pre class="code"&gt;    &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;pages&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;namespaces&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.Web&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;
        &lt;strong&gt;&amp;lt;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.Web.Controls&lt;/span&gt;" &lt;/strong&gt;&lt;span style="color: blue;"&gt;&lt;strong&gt;/&amp;gt;
&lt;/strong&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.Utilities&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.WebStore&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;namespaces&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;controls&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;assembly&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.Web&lt;/span&gt;" &lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.Web.Controls&lt;/span&gt;" &lt;span style="color: red;"&gt;tagPrefix&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;ww&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;controls&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;pages&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;which automatically includes the namespace into the page. &lt;/p&gt;

&lt;p&gt;The result is that that the DataBinder.Eval() can’t be resolved properly by the compiler – it doesn’t know which DataBinder should be used. Actually it’d be nice if the compiler was smart enough to check for the actual method Eval before throwing the error. Since my component doesn’t have a static Eval method (or any static members for that matter) it seems that the compiler should be able to prioritize the call. &lt;/p&gt;

&lt;p&gt;Ironically this error would not be an issue if this was anything but a framework provided page which is:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\DefaultWsdlHelpGenerator.aspx&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To fix the problem is easy enough by changing all the .NET 1.x DataBinder.Eval() calls with:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;# &lt;/span&gt;System.Web.UI.DataBinder.Eval(Container.DataItem, "Value.Documentation") &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;%&amp;gt;&lt;/span&gt;    &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;or &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;# &lt;/span&gt;Eval("Value.Documentation") &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;%&amp;gt;&lt;/span&gt;    &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Replacing all DataBinder.Eval instances with either code fixes the problem, but of course it only does so on my machine(s) – still a problem for anybody else. &lt;/p&gt;

&lt;p&gt;In the end there are few solutions that can be used to work around this problem – none really satisfying. The easiest and the one I actually ended up with is by removing the Westwind.Web.Controls namespace from the global ASP.NET namespace list:&lt;/p&gt;

&lt;pre class="code"&gt;      &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;namespaces&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.Web&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;
&lt;strong&gt;        &amp;lt;!--&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: green;"&gt;&lt;strong&gt;&amp;lt;add namespace="Westwind.Web.Controls" /&amp;gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;strong&gt;--&amp;gt;
&lt;/strong&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.Utilities&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;add &lt;/span&gt;&lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.WebStore&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;namespaces&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;It turns out that this works just fine in my case because the Westwind.Web.Controls namespace isn’t used much in Web page code. A while back I thankfully refactored all the utility and control code into separate namespaces, so the need for the Controls namespace is not used much if at all.&lt;/p&gt;

&lt;p&gt;The other option I was at first considering to get around this was to put the control into a separate namespace (ie. Westwind.Web.Controls.DataBinding) which certainly would have worked but this causes a number of problems when adding page register commands into the page. The following wouldn’t work:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;@ &lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Register &lt;/span&gt;&lt;span style="color: red;"&gt;Assembly&lt;/span&gt;&lt;span style="color: blue;"&gt;="Westwind.Web" &lt;/span&gt;&lt;span style="color: red;"&gt;Namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;="Westwind.Web.Controls" &lt;/span&gt;&lt;span style="color: red;"&gt;TagPrefix&lt;/span&gt;&lt;span style="color: blue;"&gt;="ww" &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;unless I also add:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue;"&gt;@ &lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Register &lt;/span&gt;&lt;span style="color: red;"&gt;Assembly&lt;/span&gt;&lt;span style="color: blue;"&gt;="Westwind.Web" &lt;/span&gt;&lt;span style="color: red;"&gt;Namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;="Westwind.Web.Controls.DataBinding" &lt;/span&gt;&lt;span style="color: red;"&gt;TagPrefix&lt;/span&gt;&lt;span style="color: blue;"&gt;="ww" &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;IOW, changing a lot of pages potentially.&lt;/p&gt;

&lt;p&gt;Finally another solution is to add web.config file into the folder with the Web Service(s) and explicitly exclude the offending namespace(s):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;xml &lt;/span&gt;&lt;span style="color: red;"&gt;version&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;1.0&lt;/span&gt;" &lt;span style="color: red;"&gt;encoding&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;UTF-8&lt;/span&gt;"&lt;span style="color: blue;"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;system.web&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;pages&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;namespaces&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;        
        &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;remove &lt;/span&gt;&lt;span style="color: red;"&gt;namespace&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Westwind.Web.Controls&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;namespaces&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;pages&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;system.web&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;configuration&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;This assumes you isolate the Web Services into a separate folder.&lt;/p&gt;

&lt;p&gt;This is obviously a very isolated incident and situation, but it’s easy to get tripped up by this. Ideally I think that the generic .NET code in DefaultWsdlHelpGenerator.aspx was namespace safe by explicitly prefixing namespaces in static method calls.&lt;/p&gt;

&lt;p&gt;There goes another couple of hours of sleuthing to find a solution. &amp;lt;shrug&amp;gt; &lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=ASP.NET'&gt;ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=Web Services'&gt;Web Services&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f61923.aspx&amp;title=Ambiguous+References+in+DefaultWsdlHelpGenerator.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f61923.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=VWiG7-lT0JM:YQR3-YPGpDo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=VWiG7-lT0JM:YQR3-YPGpDo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=VWiG7-lT0JM:YQR3-YPGpDo:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=VWiG7-lT0JM:YQR3-YPGpDo:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=VWiG7-lT0JM:YQR3-YPGpDo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=VWiG7-lT0JM:YQR3-YPGpDo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=VWiG7-lT0JM:YQR3-YPGpDo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=VWiG7-lT0JM:YQR3-YPGpDo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=VWiG7-lT0JM:YQR3-YPGpDo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/VWiG7-lT0JM" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/61923.aspx</feedburner:origLink></item>
    <item>
      <title>No JavaScript IntelliSense in VS 2010 Beta 2? Reset your Settings</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/Wqdnz2GHeNk/50857.aspx</link>
      <guid isPermaLink="false">50857_200910222152</guid>
      <pubDate>Thu, 22 Oct 2009 21:52:05 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/50857.aspx#Comments</comments>
      <slash:comments>14</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=50857</wfw:commentRss>
      <category>JavaScript</category>
      <category>Visual Studio</category>
      <description>&lt;p&gt;When I installed Visual Studio 2010 a couple of days ago I was really disappointed to see that JavaScript Intellisense failed to work completely in the new install. No workey in .js files, or ASPX pages inside of script blocks. After some back and forth with folks on the ASPInsiders list and the product teams it looks like there is an issue somewhere with the default settings that get set when Visual Studio 2010 first installs.&lt;/p&gt;  &lt;p&gt;This doesn’t affect all installs, but there were handful in a small group of folks, so this is likely going to hit a few of you trying out Visual Studio 2010 as well.&lt;/p&gt;  &lt;p&gt;To get Intellisense to work again, thanks to a tip from &lt;a href="http://msmvps.com/blogs/luisabreu/default.aspx" target="_blank"&gt;Luis Abreu&lt;/a&gt;, I ended up resetting my Visual Studio settings (Tools | Import and Export Settings):&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ResetSettings" border="0" alt="ResetSettings" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/NoJavaScriptIntelliSenseinVS2010Beta2Res_A65E/ResetSettings_00a2f134-2daa-43da-91a3-99fe2713a979.png" width="544" height="538" /&gt; &lt;/p&gt;  &lt;p&gt;then go ahead and reset to your preferred default profile (I typically choose the C# profile over the Web profile). This may seem counter intuitive immediately after a new install since I hadn’t changed any settings yet, but the reset did the trick.&lt;/p&gt;  &lt;p&gt;And voila, Intellisense in JavaScript is back.&lt;/p&gt;  &lt;p&gt;I suspect this has something to do with VS 2010 importing some existing VS 2008 settings, so even if you don’t have problems in VS 2010 it might be a good idea to actually reset all settings just to make sure there’s a clean slate to start with.&lt;/p&gt;  &lt;p&gt;Hope this helps out some of you.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Other JavaScript Editor Thoughts&lt;/h3&gt;  &lt;p&gt;One nice feature that will be quite useful is support for CodeSnippet Expansion in JavaScript, which means you can automate common tasks with keyboard expansions. Since there’s no &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/" target="_blank"&gt;CodeRush&lt;/a&gt; for VS 2010 yet and I keep typing my CR shortcuts out of habit, I guess I’m going to fix up some my more common shortcuts as code snippets (especially for ASP.NET snippets). The main reason I didn’t use Code Snippets extensively in the past is because there was no support for ASP.NET and JavaScript but now there’s much less of an excuse. While I still prefer the ease and flexibility with which you can create new shortcuts in CodeRush, the VS Code Snippet functionality is relatively nice and easy and it’s built in and easily portable to other VS installations. &lt;/p&gt;  &lt;p&gt;jQuery support (with the –vsdoc.js extension files) is now also baked in VS 2010 – jQuery Intellisense just works out of the box and it seems that Intellisense is much more snappy. No more long delays before it works even in large script files and quicker IS pop ups while typing. The JavaScript Intellisense engine (according to release notes) has been reworked to be more flexible and supposedly faster because of it and this first quick checks seem to confirm that.&lt;/p&gt;  &lt;p&gt;There are also some improvements in the code formatting behavior which in the past drove me batty with its inconsistent Indenting, re-indenting, outdenting etc. It appears that now the editor gets the intended behavior right most of the time – the result is the auto-format is a heck of a lot less jumpy than it used to be. In a few tests of a script heavy app I’m working on the auto-indenting with often nested jQuery code ended up working predictably and not jumpy as in 2008. Not exactly a new feature but&amp;#160; I’m just glad to see this working much better the way it’s supposed to.&lt;/p&gt;  &lt;p&gt;Unfortunately the JavaScript editor’s improvements in general are rather minor. There’s still no code navigation of any kind (no function list drop down or class/function/navigator) which IMHO is the biggest shortcoming of the VS JavaScript editor. Disappointed as there was some discussion that this was a coming feature for the VS 2010 editor. Anything beyond Ctrl-F to find code inside of the JS editor would be useful.&lt;/p&gt;  &lt;p&gt;Also Refactoring inside of JavaScript surely would be nice. At the very least renaming support is something I wish for in many occasions. Basic function extraction would be useful too as well as block optimization refactorings, but renaming really is the one I would like more than anything.&lt;/p&gt;  &lt;p&gt;Anyway, it looks like minor improvements at this point and let’s hold out hope there may still be additional improvements by the time VS 2010 ships.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=JavaScript'&gt;JavaScript&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=Visual Studio'&gt;Visual Studio&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f50857.aspx&amp;title=No+JavaScript+IntelliSense+in+VS+2010+Beta+2%3f+Reset+your+Settings"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f50857.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Wqdnz2GHeNk:2kKV5HrijHA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Wqdnz2GHeNk:2kKV5HrijHA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Wqdnz2GHeNk:2kKV5HrijHA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Wqdnz2GHeNk:2kKV5HrijHA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Wqdnz2GHeNk:2kKV5HrijHA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Wqdnz2GHeNk:2kKV5HrijHA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Wqdnz2GHeNk:2kKV5HrijHA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Wqdnz2GHeNk:2kKV5HrijHA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Wqdnz2GHeNk:2kKV5HrijHA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/Wqdnz2GHeNk" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/50857.aspx</feedburner:origLink></item>
    <item>
      <title>A generic way to find ASP.NET ClientIDs with jQuery</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/x5Lv96f1OnE/42319.aspx</link>
      <guid isPermaLink="false">42319_200910150904</guid>
      <pubDate>Thu, 15 Oct 2009 09:04:15 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/42319.aspx#Comments</comments>
      <slash:comments>31</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=42319</wfw:commentRss>
      <category>jQuery</category>
      <description>&lt;p&gt;I’ve been using a small hack to deal with the ASP.NET naming container morass that is so prevalent in client side development with ASP.NET. Particularly in Master Pages all server control IDs are basically munged&amp;#160; because the master page place holders are naming containers. &lt;/p&gt;  &lt;p&gt;To recap – the problem is that if you are dealing with something as simple as this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;contentcontainer&amp;quot;  &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;PageContent&amp;quot;&amp;gt;
&lt;/strong&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Stock Quote Lookup&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;labelheader&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;margin-top&lt;/span&gt;: &lt;span style="color: blue"&gt;20px&lt;/span&gt;;&lt;span style="color: blue"&gt;&amp;quot;&amp;gt;&lt;/span&gt;Enter a stock symbol:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;strong&gt;    &amp;lt;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;txtSymbol&amp;quot;  /&amp;gt; 
&lt;/strong&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;button&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btnGetQuote&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Go&amp;quot; /&amp;gt;
    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;divStockWrapper&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;divStockDetail&amp;quot;&amp;gt;        
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;imgStockChart&amp;quot;  /&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;inside of master page or even a container or user control you end up generating HTML output that looks something like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;contentcontainer&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;ctl00_MainContent_PageContent&amp;quot;&amp;gt;&lt;/strong&gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Stock Quote Lookup&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;margin-top&lt;/span&gt;: &lt;span style="color: blue"&gt;20px&lt;/span&gt;;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;labelheader&amp;quot;&amp;gt;&lt;/span&gt;Enter a stock symbol:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;&lt;strong&gt;id&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;=&amp;quot;ctl00_MainContent_txtSymbol&amp;quot;&lt;/strong&gt; &lt;br /&gt;                       &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ctl00$MainContent$txtSymbol&amp;quot; &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt; 
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;button&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Go&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btnGetQuote&amp;quot;/&amp;gt;
    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;divStockWrapper&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;divStockDetail&amp;quot;&amp;gt;        
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;imgStockChart&amp;quot;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Notice the &lt;em&gt;ctl00_MainContent&lt;/em&gt; prefixes that are added to the server controls that point to the master page and content container respectively. You get those nice and un-friendly ASP.NET naming container generated ids that are a bitch to use in client side code. You don’t want to use these generated names directly because they can easily change if you rename any of the IDs down the chain – if you change the content placeholder’s id so will the id and your script code might break because of it. Not a good idea to use those ids directly.&lt;/p&gt;

&lt;p&gt;Now if you want to access this client code you have to jump through a few hoops. A few common ways to access these values with jQuery look like this:&lt;/p&gt;

&lt;pre class="code"&gt;$(&lt;span style="color: #a31515"&gt;&amp;quot;#&amp;lt;%= txtSymbol.ClientID %&amp;gt;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;


&lt;p&gt;or slightly better more generic approach that stores all client IDs in an object globally:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;ids = { 
    txtSymbol: &lt;span style="color: #a31515"&gt;&amp;quot;#&amp;lt;%= txtSymbol.ClientID %&amp;gt;&amp;quot;&lt;/span&gt;,
    PageContent: &lt;span style="color: #a31515"&gt;&amp;quot;#&amp;lt;%= PageContainer.ClientID %&amp;gt;&amp;quot;
&lt;/span&gt;}
&lt;span style="color: green"&gt;// to use it any where in code:
&lt;/span&gt;$(&lt;span style="color: #a31515"&gt;&amp;quot;#&amp;quot; &lt;/span&gt;+ ids.txtSymbol)&lt;/pre&gt;


&lt;p&gt;The latter also partially gets around the main problem with ClientIDs in that they only work in ASPX pages not external .js files. The latter approach lets you declare only the id definitions in the main page, but the IDs can be globally accessed even in a .js file.&lt;/p&gt;

&lt;p&gt;I also posted about a ScriptVariables component that can automate this object creation&amp;#160; on the server as part of a component (&lt;a href="http://www.west-wind.com/WebLog/posts/252178.aspx" target="_blank"&gt;ScriptVariables component&lt;/a&gt; and &lt;a href="http://www.west-wind.com:8080/svn/WestwindWebToolkit/trunk/Westwind.Web/Support/ScriptVariables.cs" target="_blank"&gt;updated code&lt;/a&gt;) so you don’t have to manually map all of the client ids – the component can do it automatically (as well as a few other things like passing any values into JavaScript explicitly with proper formatting ). With this component you have a couple of lines on the server (anywhere in a Page):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ScriptVariables &lt;/span&gt;scriptVars = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ScriptVariables&lt;/span&gt;(Page, &lt;span style="color: #a31515"&gt;&amp;quot;serverVars&amp;quot;&lt;/span&gt;);
scriptVars.AddClientIds(Form, &lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;/pre&gt;


&lt;p&gt;which generates a serverVars variable into the client. You can then use the ids like so:&lt;/p&gt;

&lt;pre class="code"&gt;$(&lt;span style="color: #a31515"&gt;&amp;quot;#&amp;quot; &lt;/span&gt;+ serverVars.txtSymboldId)&lt;/pre&gt;

&lt;p&gt;All of these workarounds are pretty ugly though.&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;A better Solution&lt;/h3&gt;

&lt;p&gt;A solution I’ve been using a lot lately is by taking advantage of jQuery itself. We can search for Ids directly from JavaScript since there’s a pretty simple pattern to clientID – at least when dealing with non-repeating values.&lt;/p&gt;

&lt;p&gt;Remember a typical client ID that isn’t in a list control of some sort looks something like this: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;strong&gt;ctl00_MainContent_txtSymbol 
    &lt;br /&gt;&lt;/strong&gt;

  &lt;br /&gt;which is actually fairly easy to find with jQuery:&lt;/p&gt;

&lt;pre class="code"&gt;alert( $(&lt;span style="color: #a31515"&gt;&amp;quot;[id$=_txtSymbol]&amp;quot;&lt;/span&gt;).attr(&lt;span style="color: #a31515"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;));&lt;/pre&gt;


&lt;p&gt;You can use that directly in your JS code from anywhere that works for most situations, but while it’s not exactly complicated you still have to remember what the format of these controls looks like and how to do an attribute search. It also doesn’t deal with the case where a control might just exist on a page without a master/naming container. How many times have you created a client code page that started out as standalone page and then you later added a Master Page only to find out most of your script code is broken due to the invalid IDs? I know I have.&lt;/p&gt;

&lt;p&gt;Knowing the above though it’s easy enough to create a small routine that returns us a jQuery object based on only the id:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;$$(id, context) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;el = $(&lt;span style="color: #a31515"&gt;&amp;quot;#&amp;quot; &lt;/span&gt;+ id, context);
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(el.length &amp;lt; 1)
        el = $(&lt;span style="color: #a31515"&gt;&amp;quot;[id$=_&amp;quot; &lt;/span&gt;+ id + &lt;span style="color: #a31515"&gt;&amp;quot;]&amp;quot;&lt;/span&gt;, context);
    &lt;span style="color: blue"&gt;return &lt;/span&gt;el;
}&lt;/pre&gt;

&lt;p&gt;This code uses jQuery to first do a plain ID search and the behavior of the function is the same as the native jQuery constructor except for the specific selector implementation that only finds IDs. Just as with jQuery you can pass in a relative selector context ( a jQuery object or DOM Element) that limits the search to children of that elements’ level in the DOM hierarchy.&lt;/p&gt;

&lt;p&gt;If the function finds a direct match on the ID that’s returned. If not it checks to see if a context was passed. A context is the container context and if passed the search here is limited to that specific container and its immediate children. This is meant to make it easier to isolate naming containers in case there is a possibility of overlapping names so you can drill into a specific user control for example.&lt;/p&gt;

&lt;p&gt;So in simple usage to select my &lt;strong&gt;ctl00_MainContent_txtSymbol&lt;/strong&gt; value both of the following work:&lt;/p&gt;

&lt;pre class="code"&gt;alert( $$(&lt;span style="color: #a31515"&gt;&amp;quot;txtSymbol&amp;quot;&lt;/span&gt;).attr(&lt;span style="color: #a31515"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;) );&lt;/pre&gt;

&lt;p&gt;Or if I want to be specific about the container:&lt;/p&gt;

&lt;pre class="code"&gt;alert( $$(&lt;span style="color: #a31515"&gt;&amp;quot;txtSymbol&amp;quot;&lt;/span&gt;,$(&lt;span style="color: #a31515"&gt;&amp;quot;#wrapper&amp;quot;&lt;/span&gt;)).attr(&lt;span style="color: #a31515"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;) );&lt;/pre&gt;

&lt;p&gt;This is a low impact approach to dealing with client ids that is easy to type and understand. Obviously you can name this function anything you chose – the $$ just seemed like a good choice to me that doesn’t conflict with anything that jQuery isn’t already conflicting with :-}. I suppose it would also be possible to create a special selector operator in jQuery for this, but I think I actually like the single function implementation better even though it lives outside of jQuery.&lt;/p&gt;

&lt;p&gt;Please realize that this won’t address all scenarios where naming container variables might be involved. Specifically this function only deals with the simple ASP.NET variable case – it doesn’t deal with list controls that output sequentially numbered ids, but then that’s not really been an issue for me. I don’t think one often searches for list items by ID directly – they are usually accessed by event behavior or iteration – rarely directly by ID. &lt;/p&gt;

&lt;p&gt;Single controls however - I constantly access to get or set values on and manipulate items. While I get more and more away from using server controls at all there are still plenty of times when naming container naming ends up in markup and this makes using these controls a no-brainer.&lt;/p&gt;

&lt;h3&gt;Performance&lt;/h3&gt;

&lt;p&gt;Also realize that doing attribute selector searches are fairly slow (but then ‘slow’ is relative). If you have very large documents with lots of elements and you’re doing many lookups using this function you may run into slow performance issues. If that’s the case using the original concept of a global variable that holds all the ids – either manually created or via the ScriptVariables component from the &lt;a href="http://www.west-wind.com/westwindwebtoolkit/" target="WebToolkit"&gt;West Wind Web Toolkit&lt;/a&gt; –&amp;#160; to get better performance. Because that approach uses direct element ids it’s very efficient as ID lookups in a document are among the fastest lookups the DOM can perform.&lt;/p&gt;

&lt;p&gt;So as usual there are trade-offs – you’re trading convenience over performance with the $$() function I showed here.&lt;/p&gt;

&lt;p&gt;I hope some of you find this simple solution useful.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=jQuery'&gt;jQuery&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f42319.aspx&amp;title=A+generic+way+to+find+ASP.NET+ClientIDs+with+jQuery"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f42319.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=x5Lv96f1OnE:tqlU0EEmrwY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=x5Lv96f1OnE:tqlU0EEmrwY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=x5Lv96f1OnE:tqlU0EEmrwY:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=x5Lv96f1OnE:tqlU0EEmrwY:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=x5Lv96f1OnE:tqlU0EEmrwY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=x5Lv96f1OnE:tqlU0EEmrwY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=x5Lv96f1OnE:tqlU0EEmrwY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=x5Lv96f1OnE:tqlU0EEmrwY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=x5Lv96f1OnE:tqlU0EEmrwY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/x5Lv96f1OnE" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/42319.aspx</feedburner:origLink></item>
    <item>
      <title>LINQ to SQL, Lazy Loading and Prefetching</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/hM5mfCQqc1w/38838.aspx</link>
      <guid isPermaLink="false">38838_200910120956</guid>
      <pubDate>Mon, 12 Oct 2009 09:56:53 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/38838.aspx#Comments</comments>
      <slash:comments>9</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=38838</wfw:commentRss>
      <category>LINQ</category>
      <category>CSharp</category>
      <description>&lt;p&gt;LINQ to SQL by default loads related entities and entity sets by using Lazy Loading. Which means if you retrieve a list of entities in a query that references other entities these other entities are not actually loaded unless you physically access them. Lazy loading is quite useful in some scenarios – typically when you load up individual instances for display purposes in simple record based UIs, but it can be a real problem when displaying list based data that needs to have access to related data. In related list scenarios it’s quite easy to have a list that has 100 records displayed on a page to fire off 100 hundred child queries to retrieve the related data – clearly in most cases that’s quite undesirable.&lt;/p&gt;  &lt;p&gt;Lets look at an example, from my Time Trakker sample application for the LINQ to SQL business layer.&lt;/p&gt;  &lt;p&gt;In my Time Trakker app I have time entries that can be queried. An entry has a related project and customer which in turn can be referenced through the project:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="TimeTrakkerModel" border="0" alt="TimeTrakkerModel" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/LINQtoSQLLazyLoadingandDenormalizing_C3D0/TimeTrakkerModel_61cfe32f-c609-4cd1-920a-fa8694f389c5.png" width="852" height="498" /&gt; &lt;/p&gt;  &lt;p&gt;So if I have an EntryEntity I can get a project with Entry.ProjectEntity and a customer with Entry.ProjectEntity.CustomerEntity. So far so good.&lt;/p&gt;  &lt;p&gt;Now in my businesslayer I have a routine that basically allows me to query this model for a timesheet report by passing in a bunch of report parameters via a parameter object like so:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt; GetTimeSheetByClient(&lt;span style="color: #2b91af"&gt;TimesheetReportParameters &lt;/span&gt;parms)
{                        
    &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt; result =
        &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;Context.EntryEntities
        &lt;span style="color: blue"&gt;where &lt;/span&gt;entry.TimeIn &amp;gt;= parms.FromDate &amp;amp;&amp;amp; 
              entry.TimeIn &amp;lt; parms.ToDate.Date.AddDays(1) &amp;amp;&amp;amp;
              entry.PunchedOut &amp;amp;&amp;amp;
              parms.Companies.Contains(entry.CustomerPk)
        &lt;span style="color: blue"&gt;orderby &lt;/span&gt;entry.ProjectEntity.Customer.Company, entry.ProjectEntity.ProjectName, entry.TimeIn 
        &lt;span style="color: blue"&gt;select &lt;/span&gt;entry;

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(parms.BillType == &lt;span style="color: #a31515"&gt;&amp;quot;Unbilled&amp;quot;&lt;/span&gt;)
        result = result.Where(e =&amp;gt; !e.Billed);
    &lt;span style="color: blue"&gt;else if &lt;/span&gt;(parms.BillType == &lt;span style="color: #a31515"&gt;&amp;quot;Billed&amp;quot;&lt;/span&gt;)
        result = result.Where(e =&amp;gt; e.Billed);
    
    &lt;span style="color: blue"&gt;return &lt;/span&gt;result;
}&lt;/pre&gt;


&lt;p&gt;The parameter object has things like a date range, which type of entries to retrieve and so on which are applied against the mode in the query consecutively. This incremental building up of queries using Linq’s fluent language interface is one of my favorite LINQ features. The result of this query is then returned as an IQueryable&amp;lt;EntryEntity&amp;gt;.&lt;/p&gt;

&lt;p&gt;When I retrieve this list of entries in the ASP.NET front end I end up databinding it and then binding to the data inside of a ListView control. The data used is mostly from the Entry Entity but there’s also some data displayed from the customer and project. Here’s what the html based report looks like:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Repport" border="0" alt="Repport" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/LINQtoSQLLazyLoadingandDenormalizing_C3D0/Repport_98f1f0ec-6952-4634-9579-0ab0b2e4e258.png" width="892" height="488" /&gt;&lt;/p&gt;

&lt;p&gt;Notice the headers which include the customer name and project name which come from related entities.&lt;/p&gt;

&lt;p&gt;Now when the report runs it loads the report like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;protected void &lt;/span&gt;ProcessReport()
  {            
      &lt;span style="color: blue"&gt;this&lt;/span&gt;.ReportParameters.Companies.Clear();

      &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ListItem &lt;/span&gt;item &lt;span style="color: blue"&gt;in this&lt;/span&gt;.lstCustomers.Items)
      {
          &lt;span style="color: blue"&gt;if &lt;/span&gt;(item.Selected)
              &lt;span style="color: blue"&gt;this&lt;/span&gt;.ReportParameters.Companies.Add(&lt;span style="color: blue"&gt;int&lt;/span&gt;.Parse(item.Value));
      }

      &lt;span style="color: blue"&gt;this&lt;/span&gt;.DataBinder.Unbind();

      &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.DataBinder.BindingErrors.Count  &amp;gt; 0)
      {
          &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(&lt;span style="color: blue"&gt;this&lt;/span&gt;.DataBinder.BindingErrors.ToHtml(), &lt;span style="color: #a31515"&gt;&amp;quot;Please correct the following&amp;quot;&lt;/span&gt;);
          &lt;span style="color: blue"&gt;return&lt;/span&gt;;
      }

      &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt; entries = &lt;strong&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.Entry.GetTimeSheetByClient(&lt;span style="color: blue"&gt;this&lt;/span&gt;.ReportParameters);&lt;/strong&gt;

&lt;span style="color: green"&gt;      // We'll dynamically load the ReportView User Control View, bind it then render
      &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimeSheetReport &lt;/span&gt;rep = &lt;span style="color: blue"&gt;this&lt;/span&gt;.LoadControl(&lt;span style="color: #a31515"&gt;&amp;quot;~/Reports/TimeSheetReport.ascx&amp;quot;&lt;/span&gt;) &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimeSheetReport&lt;/span&gt;;
     &lt;strong&gt; rep.BindData(entries, &lt;span style="color: blue"&gt;this&lt;/span&gt;.ReportParameters);&lt;/strong&gt;

      this.RenderReport(rep);&lt;br /&gt;}&lt;/pre&gt;


&lt;p&gt;then the actual binding in the report to the listview the TimeSheetReport control:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;BindData(&lt;span style="color: #2b91af"&gt;IQueryable &lt;/span&gt;query, &lt;span style="color: blue"&gt;object &lt;/span&gt;parameters)
{
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.Parameters = parameters &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimesheetReportParameters&lt;/span&gt;;

    &lt;strong&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.entryList= (query &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt;).ToList();
&lt;/strong&gt;
    &lt;strong&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.lstReport.DataSource = &lt;span style="color: blue"&gt;this&lt;/span&gt;.entryList; &lt;br /&gt;&lt;/strong&gt;    &lt;span style="color: blue"&gt;this&lt;/span&gt;.lstReport.DataBind();            
}&lt;/pre&gt;


&lt;p&gt;And finally the data is actually bound:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListView &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;lstReport&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ItemPlaceholderID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;layoutContainer&amp;quot;  &amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;LayoutTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;layoutContainer&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; /&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;LayoutTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;    
    
&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# this&lt;/span&gt;.RenderProjectGroupHeader(Container.DataItem &lt;span style="color: blue"&gt;as &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;) &lt;/strong&gt;&lt;span style="background: #ffee62"&gt;&lt;strong&gt;%&amp;gt;
&lt;/strong&gt;&lt;/span&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemcontainer&amp;quot;&amp;gt;    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemheader&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;Eval(&lt;span style="color: #a31515"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;) &lt;span style="background: #ffee62"&gt;%&amp;gt;   &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;table &lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;90%&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;cellpadding&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;5&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;valign&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;top&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;:&lt;span style="color: blue"&gt;120px&lt;/span&gt;;&lt;span style="color: blue"&gt;&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;small&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimeUtils&lt;/span&gt;.ShortDateString((&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;) Eval(&lt;span style="color: #a31515"&gt;&amp;quot;TimeIn&amp;quot;&lt;/span&gt;),&lt;span style="color: blue"&gt;true&lt;/span&gt;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;br &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
    &lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimeUtils&lt;/span&gt;.ShortDateString((&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;) Eval(&lt;span style="color: #a31515"&gt;&amp;quot;TimeOut&amp;quot;&lt;/span&gt;),&lt;span style="color: blue"&gt;true&lt;/span&gt;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;small&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;valign&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;top&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;Eval(&lt;span style="color: #a31515"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;valign&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;top&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;width&lt;/span&gt;: &lt;span style="color: blue"&gt;70px&lt;/span&gt;;&lt;span style="color: blue"&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimeUtils&lt;/span&gt;.FractionalHoursToString( (&lt;span style="color: blue"&gt;decimal&lt;/span&gt;) Eval(&lt;span style="color: #a31515"&gt;&amp;quot;TotalHours&amp;quot;&lt;/span&gt;), &lt;span style="color: #a31515"&gt;&amp;quot;{0}h {1}min&amp;quot; &lt;/span&gt;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;table&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;        
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# this&lt;/span&gt;.RenderProjectFooter(Container) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;    
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListView&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;The main data displayed for each entry all comes from the Entry entity and that’s fine. However there RenderProjectGroupHeader() method figures out whether the group changed and based on this needs to access the Customer and Project information.&lt;/p&gt;

&lt;pre class="code"&gt;        &lt;span style="color: blue"&gt;protected string &lt;/span&gt;RenderProjectGroupHeader(&lt;span style="color: #2b91af"&gt;EntryEntity  &lt;/span&gt;entry)
        {
            &lt;span style="color: blue"&gt;string &lt;/span&gt;output = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;

            &lt;span style="color: green"&gt;// if the project name has changed render a group as a &amp;lt;div&amp;gt; header
           &lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(entry.ProjectEntity.ProjectName != lastProjectName)&lt;/strong&gt;
            {
                lastProjectName = &lt;strong&gt;entry.ProjectEntity.ProjectName;&lt;/strong&gt;
                
                &lt;span style="color: green"&gt;// *** New project add hours for first time
                &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.groupTotalHours = entry.TotalHours;

                &lt;span style="color: blue"&gt;string &lt;/span&gt;html = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(
&lt;span style="color: #a31515"&gt;@&amp;quot;&amp;lt;div class='groupheader'&amp;gt;
    &amp;lt;div style='float:right'&amp;gt;&amp;lt;small&amp;gt;{0}&amp;lt;/small&amp;gt;&amp;lt;/div&amp;gt;
    {1}
&amp;lt;/div&amp;gt;
&amp;quot;&lt;/span&gt;, entry.ProjectEntity.Customer.Company, entry.ProjectEntity.ProjectName);

                &lt;span style="color: blue"&gt;return &lt;/span&gt;html;
            }
            &lt;span style="color: blue"&gt;else
                this&lt;/span&gt;.groupTotalHours += entry.TotalHours;
            
            &lt;span style="color: blue"&gt;this&lt;/span&gt;.grandtotalHours += entry.TotalHours;

            &lt;span style="color: blue"&gt;return &lt;/span&gt;output;
        }&lt;/pre&gt;


&lt;p&gt;And here you can see the child entities being accessed.&lt;/p&gt;

&lt;p&gt;Now the report works fine with this code. But if you actually look at this SQL generated for this report you’ll find that this query causes a flurry of activity against the server:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Profiler" border="0" alt="Profiler" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/LINQtoSQLLazyLoadingandDenormalizing_C3D0/Profiler_d1c9a14d-557e-4a78-b8d8-865c4b7833ac.png" width="830" height="589" /&gt; &lt;/p&gt;

&lt;p&gt;It turns out that each access to the ProjectEntity and CustomerEntity object causes a separate query to the server (shown) for the first time a particular Project or Entity is referenced. This means for each project in the application there will be two additional queries hitting the server so if I show 20 projects I’ll hit the database 40 extra times. That’s lazy loading for you and it’s usually a problem in list based displays like this. It can be much worse if EVERY row you display requires one or more related entities.&lt;/p&gt;

&lt;h3&gt;Working around Lazy Loading in LINQ to SQL&lt;/h3&gt;

&lt;p&gt;LINQ to SQL loads related entities and entity sets using lazy loading. Oddly you can’t override this behavior either in the model – even though you can delay load individual properties (like large text, image or XML fields). So everything always lazy loads.&lt;/p&gt;

&lt;h3&gt;DataLoadOptions for Prefetching&lt;/h3&gt;

&lt;p&gt;There’s a mechanism that allows you to specify prefetching using the DataLoadOptions which looks like this when applied GetTimeSheetByClient():&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt; GetTimeSheetByClient(&lt;span style="color: #2b91af"&gt;TimesheetReportParameters &lt;/span&gt;parms)
{            
&lt;strong&gt;    &lt;span style="color: #2b91af"&gt;DataLoadOptions &lt;/span&gt;options = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataLoadOptions&lt;/span&gt;();
    options.LoadWith&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt;(c =&amp;gt; c.ProjectEntity);
    options.LoadWith&amp;lt;&lt;span style="color: #2b91af"&gt;ProjectEntity&lt;/span&gt;&amp;gt;(p =&amp;gt; p.Customer);
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.Context.LoadOptions = options;&lt;/strong&gt;

    &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt; result =
        &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;Context.EntryEntities
        &lt;span style="color: blue"&gt;where &lt;/span&gt;entry.TimeIn &amp;gt;= parms.FromDate &amp;amp;&amp;amp; 
              entry.TimeIn &amp;lt; parms.ToDate.Date.AddDays(1) &amp;amp;&amp;amp;
              entry.PunchedOut &amp;amp;&amp;amp;
              parms.Companies.Contains(entry.CustomerPk)
        &lt;span style="color: blue"&gt;orderby &lt;/span&gt;entry.ProjectEntity.Customer.Company, entry.ProjectEntity.ProjectName, entry.TimeIn 
        &lt;span style="color: blue"&gt;select &lt;/span&gt;entry;

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(parms.BillType == &lt;span style="color: #a31515"&gt;&amp;quot;Unbilled&amp;quot;&lt;/span&gt;)
        result = result.Where(e =&amp;gt; !e.Billed);
    &lt;span style="color: blue"&gt;else if &lt;/span&gt;(parms.BillType == &lt;span style="color: #a31515"&gt;&amp;quot;Billed&amp;quot;&lt;/span&gt;)
        result = result.Where(e =&amp;gt; e.Billed);
    
    &lt;span style="color: blue"&gt;return &lt;/span&gt;result;
}&lt;/pre&gt;


&lt;pre class="code"&gt;&amp;#160;&lt;/pre&gt;


&lt;p&gt;This works and results in one large SQL statement that preloads the customer and project child entities.&lt;/p&gt;

&lt;p&gt;However, this approach is problematic in a number of ways if you’re like me using a persistent data context. In my applications I scope a data context to a business object, so multiple operations may be performed against a single data context instance. If you have more than one operation that’s called and setting the DataLoad options it’s easy to clobber the settings on this object. A common problem when you have a persistent object like the DataContext and with L2S it’s difficult to get away from storing the context in some sort of persistent mechanism as it’s a connected ORM.&lt;/p&gt;

&lt;p&gt;The fact that the options are tied to the DataContext rather than the query itself also makes it much more difficult to customize the query externally depending on the usage of the result. I often pass out an iQueryable and allow customization of the result set. Outside of the business layer the DataContext and therefore the options are not available and so it can’t be set externally.&lt;/p&gt;

&lt;p&gt;Finally the DataOptions are tied to full related entities. If you just want to preload a property or two (like ProjectName and Company in our example here) you’re out of luck. DataOptions only deal with full entities.&lt;/p&gt;

&lt;h3&gt;Using Projection to Force Pre-Fetching&lt;/h3&gt;

&lt;p&gt;But there’s another way to write your queries differently to effectively force LINQ to SQL to prefetch by using projection in the Select clause of the LINQ statement. Basically the idea is to project the related entities or simple properties at the top level of the returned result to force the data to be denormalized and so becomes effectively preloaded.&lt;/p&gt;

&lt;p&gt;So back to the example, if I want to load both the Project and Customer instances completely I can force the query to project into a type like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ReportEntryItem
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EntryEntity &lt;/span&gt;Entry {&lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;;}
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CustomerEntity &lt;/span&gt;Customer {&lt;span style="color: blue"&gt;get&lt;/span&gt;;&lt;span style="color: blue"&gt;set&lt;/span&gt;;}
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ProjectEntity &lt;/span&gt;Project { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;

&lt;p&gt;I’m using an explicit type declaration here rather than an anonymous type because the helper methods of the report rely on an entity instance to retrieve customer and project information and an Anonymous object would not allow access of properties beyond the declared query scope. The explicit object gives me a strongly typed object I can pass around the report UI methods without resorting to Reflection. If you don’t pass the returned result around and bind it immediately the explicit type is not required which is one less thing to declare.&lt;/p&gt;

&lt;p&gt;With the new type in place, BindData then changes the query code to look like this:&lt;/p&gt;


&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt; entryList;

    &lt;br /&gt;&lt;span style="color: blue"&gt;public void&lt;/span&gt;BindData(&lt;span style="color: #2b91af"&gt;IQueryable &lt;/span&gt;query, &lt;span style="color: blue"&gt;object&lt;/span&gt;parameters)

    &lt;br /&gt;{

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;this&lt;/span&gt;.Parameters = parameters &lt;span style="color: blue"&gt;as&lt;/span&gt;&lt;span style="color: #2b91af"&gt;TimesheetReportParameters&lt;/span&gt;;

    &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var &lt;/span&gt;q = query &lt;span style="color: blue"&gt;as&lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;EntryEntity&lt;/span&gt;&amp;gt;;

    &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: green"&gt;&lt;font face="Courier New"&gt;// denormalize the list so we minimize related queries
      &lt;br /&gt;&lt;strong&gt;&amp;#160;&amp;#160; &lt;/strong&gt;&lt;/font&gt;&lt;/span&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;res = &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;q

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;select new&lt;/span&gt;&lt;/font&gt;&lt;/strong&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;&lt;span style="color: #2b91af"&gt;ReportEntryItem
        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Entry = entry,

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Project = entry.ProjectEntity,

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Customer = entry.ProjectEntity.Customer

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;/strong&gt;

    &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: green"&gt;// in this case we want a List&amp;lt;T&amp;gt; so we can lazy load more data
      &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.entryList = res.ToList(); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;this&lt;/span&gt;.lstReport.DataSource = &lt;span style="color: blue"&gt;this&lt;/span&gt;.entryList; 

    &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;


&lt;p&gt;Now when the ToList() executes I get a single denormalized and very large record for each row that includes the data for Entry, Customer and Project in the generated SQL:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;exec &lt;/span&gt;&lt;span style="color: maroon"&gt;sp_executesql &lt;/span&gt;&lt;span style="color: red"&gt;N'SELECT [t0].[Pk], [t0].[CustomerPk], [t0].[ProjectPk], [t0].[InvoicePk], &lt;br /&gt;[t0].[UserPk], [t0].[Title], [t0].[Description], [t0].[TimeIn], [t0].[TimeOut], [t0].[PunchedOut], &lt;br /&gt;[t0].[Qty], [t0].[Rate], [t0].[TotalHours], [t0].[ItemTotal], [t0].[Taxable], [t0].[Billed], &lt;br /&gt;[t0].[Imported], [t0].[Xml], [t0].[tversion], [t3].[test], [t3].[Pk] AS [Pk2], [t3].[LastName], &lt;br /&gt;[t3].[FirstName], [t3].[Company], [t3].[Address], [t3].[City], [t3].[State], [t3].[Zip], &lt;br /&gt;[t3].[Country], [t3].[CountryId], [t3].[Phone], [t3].[Email], [t3].[Fax], [t3].[Notes], &lt;br /&gt;[t3].[Entered], [t3].[Updated], [t3].[LastOrder], [t3].[BillingRate], [t3].[Xml] AS [Xml2], &lt;br /&gt;[t3].[tversion] AS [tversion2], [t1].[Pk] AS [Pk3], [t1].[CustomerPk] AS [CustomerPk2], &lt;br /&gt;[t1].[ProjectName], [t1].[Entered] AS [Entered2], [t1].[StartDate], [t1].[EndDate], &lt;br /&gt;[t1].[Status], [t1].[tversion] AS [tversion3]
FROM [dbo].[Entries] AS [t0]
INNER JOIN [dbo].[Projects] AS [t1] ON [t1].[Pk] = [t0].[ProjectPk]
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t2].[Pk], [t2].[LastName], [t2].[FirstName], [t2].[Company], [t2].[Address], [t2].[City], [t2].[State], [t2].[Zip], [t2].[Country], [t2].[CountryId], [t2].[Phone], [t2].[Email], [t2].[Fax], [t2].[Notes], [t2].[Entered], [t2].[Updated], [t2].[LastOrder], [t2].[BillingRate], [t2].[Xml], [t2].[tversion]
    FROM [dbo].[Customers] AS [t2]
    ) AS [t3] ON [t3].[Pk] = [t1].[CustomerPk]
WHERE (NOT ([t0].[Billed] = 1)) AND ([t0].[TimeIn] &amp;gt;= @p0) AND ([t0].[TimeIn] &amp;lt; @p1) AND ([t0].[PunchedOut] = 1) AND ([t0].[CustomerPk] IN (@p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18))
ORDER BY [t3].[Company], [t1].[ProjectName], [t0].[TimeIn]'&lt;/span&gt;&lt;span style="color: gray"&gt;,&lt;/span&gt;&lt;span style="color: red"&gt;N'@p0 datetime,@p1 datetime,@p2 int,@p3 int,@p4 int,@p5 int,@p6 int,@p7 int,@p8 int,@p9 int,@p10 int,@p11 int,@p12 int,@p13 int,@p14 int,@p15 int,@p16 int,@p17 int,@p18 int'&lt;/span&gt;&lt;span style="color: gray"&gt;,&lt;/span&gt;@p0&lt;span style="color: gray"&gt;=&lt;/span&gt;&lt;span style="color: red"&gt;'2009-01-09 00:00:00'&lt;/span&gt;&lt;span style="color: gray"&gt;,&lt;/span&gt;@p1&lt;span style="color: gray"&gt;=&lt;/span&gt;&lt;span style="color: red"&gt;'2009-10-10 00:00:00'&lt;/span&gt;&lt;span style="color: gray"&gt;,&lt;/span&gt;@p2&lt;span style="color: gray"&gt;=&lt;/span&gt;25&lt;span style="color: gray"&gt;,&lt;/span&gt;@p3&lt;span style="color: gray"&gt;=&lt;/span&gt;2&lt;span style="color: gray"&gt;,&lt;/span&gt;@p4&lt;span style="color: gray"&gt;=&lt;/span&gt;40&lt;span style="color: gray"&gt;,&lt;/span&gt;@p5&lt;span style="color: gray"&gt;=&lt;/span&gt;41&lt;span style="color: gray"&gt;,&lt;/span&gt;@p6&lt;span style="color: gray"&gt;=&lt;/span&gt;42&lt;span style="color: gray"&gt;,&lt;/span&gt;@p7&lt;span style="color: gray"&gt;=&lt;/span&gt;15&lt;span style="color: gray"&gt;,&lt;/span&gt;@p8&lt;span style="color: gray"&gt;=&lt;/span&gt;26&lt;span style="color: gray"&gt;,&lt;/span&gt;@p9&lt;span style="color: gray"&gt;=&lt;/span&gt;45&lt;span style="color: gray"&gt;,&lt;/span&gt;@p10&lt;span style="color: gray"&gt;=&lt;/span&gt;44&lt;span style="color: gray"&gt;,&lt;/span&gt;@p11&lt;span style="color: gray"&gt;=&lt;/span&gt;16&lt;span style="color: gray"&gt;,&lt;/span&gt;@p12&lt;span style="color: gray"&gt;=&lt;/span&gt;3&lt;span style="color: gray"&gt;,&lt;/span&gt;@p13&lt;span style="color: gray"&gt;=&lt;/span&gt;24&lt;span style="color: gray"&gt;,&lt;/span&gt;@p14&lt;span style="color: gray"&gt;=&lt;/span&gt;23&lt;span style="color: gray"&gt;,&lt;/span&gt;@p15&lt;span style="color: gray"&gt;=&lt;/span&gt;4&lt;span style="color: gray"&gt;,&lt;/span&gt;@p16&lt;span style="color: gray"&gt;=&lt;/span&gt;43&lt;span style="color: gray"&gt;,&lt;/span&gt;@p17&lt;span style="color: gray"&gt;=&lt;/span&gt;39&lt;span style="color: gray"&gt;,&lt;/span&gt;@p18&lt;span style="color: gray"&gt;=&lt;/span&gt;1&lt;/pre&gt;


&lt;p&gt;Denormalized alright, but what this does is effectively provides the necessary data for all Entry, Project and Customer entities to be completely filled.&lt;/p&gt;

&lt;p&gt;For the ListViewItem template this means that individual controls now bind to Entity.Field:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemheader&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;Eval(&lt;span style="color: #a31515"&gt;&amp;quot;Entity.Title&amp;quot;&lt;/span&gt;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;        &lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;instead of just binding to the Title before. I can also directly access the project now without reloading:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemheader&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;Eval(&lt;span style="color: #a31515"&gt;&amp;quot;Entity.Project.ProjectName&amp;quot;&lt;/span&gt;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;incidentally the following also works now without another trip to the database:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemheader&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;# &lt;/span&gt;Eval(&lt;span style="color: #a31515"&gt;&amp;quot;Entity.Entry.ProjectEntity.ProjectName&amp;quot;&lt;/span&gt;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;To demonstrate in the example, the report header function now receives the report item as a parameter and gets a repItem.Entry from it. Otherwise there are no changes in that code from before:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;protected string &lt;/span&gt;RenderProjectGroupHeader(&lt;span style="color: #2b91af"&gt;ReportEntryItem  &lt;/span&gt;repItem)
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;output = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
&lt;strong&gt;    &lt;span style="color: #2b91af"&gt;EntryEntity &lt;/span&gt;entry = repItem.Entry;&lt;/strong&gt;

    &lt;span style="color: green"&gt;// if the project name has changed render a group as a &amp;lt;div&amp;gt; header
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;strong&gt;entry.ProjectEntity.ProjectName&lt;/strong&gt; != lastProjectName)
    {
        lastProjectName = entry.ProjectEntity.ProjectName;
        
        &lt;span style="color: green"&gt;// *** New project add hours for first time
        &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.groupTotalHours = entry.TotalHours;

        &lt;span style="color: blue"&gt;string &lt;/span&gt;html = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(
&lt;span style="color: #a31515"&gt;@&amp;quot;&amp;lt;div class='groupheader'&amp;gt;
&amp;lt;div style='float:right'&amp;gt;&amp;lt;small&amp;gt;{0}&amp;lt;/small&amp;gt;&amp;lt;/div&amp;gt;
{1}
&amp;lt;/div&amp;gt;
&amp;quot;&lt;/span&gt;, entry.ProjectEntity.Customer.Company, entry.ProjectEntity.ProjectName);

        &lt;span style="color: blue"&gt;return &lt;/span&gt;html;
    }
    &lt;span style="color: blue"&gt;else
        this&lt;/span&gt;.groupTotalHours += entry.TotalHours;
    
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.grandtotalHours += entry.TotalHours;

    &lt;span style="color: blue"&gt;return &lt;/span&gt;output;
}&lt;/pre&gt;

&lt;p&gt;Note that I can still bind to entry.ProjectEntity.ProjectName and this works without another trip to the database because the Project entity was preloaded in the repItem.Project property. This the same instance that’s referenced in entry.ProjectEntity just as repItem.CustomerEntity is the same entry.ProjectEntity.CustomerEntity. &lt;/p&gt;

&lt;p&gt;By including the Customer and Project entities as projected values in the query we’ve forced them to preload and we've reduced 40 queries to just a single (but large and redundant) query.&lt;/p&gt;

&lt;h3&gt;Watch what you Load&lt;/h3&gt;

&lt;p&gt;This example loads the full customer and project entities, but realistically we only need the Company and ProjectName fields from the respective related tables. If you know up front you only need a few of the fields in a table it’s more efficient to load just that data in the projection which has roughly the same effect. Again this is easier if you can use an anonymous type, otherwise the projected type instance has to reflect this layout.&lt;/p&gt;

&lt;p&gt;The following is quite a bit more efficient than retrieving the full entities:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;res = &lt;span style="color: blue"&gt;from &lt;/span&gt;entry &lt;span style="color: blue"&gt;in &lt;/span&gt;q
 &lt;span style="color: blue"&gt;select new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ReportEntryItem
 &lt;/span&gt;{
     Entry = entry,
     ProjectName = entry.ProjectEntity.ProjectName,
     Company = entry.ProjectEntity.CustomerEntity.Company
 };&lt;/pre&gt;


&lt;p&gt;because it reduces the amount of field data for each row of SQL result data significantly.&lt;/p&gt;

&lt;p&gt;You have to be careful with this though – in the above scenario if I access entry.Entry.ProjectEntity.CustomerEntity.Address I will end up lazy loading both the Project and Customer records from the database. In this instance only the ProjectName and Company were retrieved, not the entire entities. IOW, if you pull just a few fields of related entities make sure you stick to using only those fields and leave the actual related entities alone.&lt;/p&gt;

&lt;h3&gt;To Lazy Load or Not to Lazy Load&lt;/h3&gt;

&lt;p&gt;Arguably LINQ to SQL’s lazy loading functionality behavior without override ability is not exactly intuitive, but it’s not terribly complex to force it to return pre-loaded data either. It does require some foresight as switching between lazy loaded and pre-loaded entities effectively requires some code changes to reflect the project type’s structure. It would be much nicer if there was syntax that would let you specify a prefetch path right on the query (something I really like about &lt;a href="http://www.llblgen.com/pages/secure/entrance.aspx" target="_blank"&gt;llblGen&lt;/a&gt;’s LINQ implementation).&lt;/p&gt;

&lt;p&gt;Also keep in mind that lazy loading isn’t always bad so this isn’t something that should be done on every query. Denormalized data retrieves a lot of repetitive data so you’re often sacrificing data on the wire for fewer round trips to the database. In many situations – especially record level CRUD operations – lazy loading is usually a great&amp;#160; way to go. Even small list based displays might not suffer severely from many requests to retrieve data vs. running a single query to retrieve the data you need. Also keep in mind that child items don’t necessarily load for EACH and every row, but only the first time a particular instance is loaded, whereas a denormalized query ALWAYS retrieves the related data for every row. So a list with a lot of repeated related data may not actually access the database as often as you might thing. It’s a tradeoff and experimentation is required to see what works best in each situation. But with a little bit of extra work you can make L2S do what you need it to.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=LINQ'&gt;LINQ&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=CSharp'&gt;CSharp&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f38838.aspx&amp;title=LINQ+to+SQL%2c+Lazy+Loading+and+Prefetching"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f38838.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=hM5mfCQqc1w:LLZarL_XSx8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=hM5mfCQqc1w:LLZarL_XSx8:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=hM5mfCQqc1w:LLZarL_XSx8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=hM5mfCQqc1w:LLZarL_XSx8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=hM5mfCQqc1w:LLZarL_XSx8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=hM5mfCQqc1w:LLZarL_XSx8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=hM5mfCQqc1w:LLZarL_XSx8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=hM5mfCQqc1w:LLZarL_XSx8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=hM5mfCQqc1w:LLZarL_XSx8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/hM5mfCQqc1w" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/38838.aspx</feedburner:origLink></item>
    <item>
      <title>Application that won&amp;rsquo;t Pin to Taskbar in Windows 7</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/pvVDFJ3gbDc/32765.aspx</link>
      <guid isPermaLink="false">32765_200910080902</guid>
      <pubDate>Thu, 08 Oct 2009 09:02:57 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/32765.aspx#Comments</comments>
      <slash:comments>19</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=32765</wfw:commentRss>
      <category>Vista</category>
      <category>Windows</category>
      <description>&lt;p&gt;Ok, so I have one of my applications (&lt;a href="http://www.west-wind.com/wwhelp/" target="top"&gt;Html Help Builder&lt;/a&gt;) that will not pin to the taskbar in Windows 7. This is an application I’ve created and have full control over in terms of build, but I can’t figure out &lt;strong&gt;why&lt;/strong&gt; it will not pin to the Windows 7 taskbar. All other applications pin just fine, but this particular one will not pin or be dragged onto the taskbar. Not from a running application, not from a dragged shortcut or by using the context menu to pin it to the taskbar. The Task menu that pops up has nothing more than a Close this Application on it instead of the usual pin options.     &lt;br&gt;    &lt;br&gt;&lt;img style="border-width: 0px; display: inline;" title="NoPinContext" alt="NoPinContext" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/ApplicationthatwontPintoTaskbarinWindows_135AC/NoPinContext_ca50c0fe-29d8-4b50-b157-7a2498e20a46.png" width="1043" border="0" height="635"&gt; &lt;/p&gt;  &lt;p&gt;Notice that this looks very different from a typical application which shows the actual application instance(s) running plus the Pin this program to taskbar:    &lt;br&gt;    &lt;br&gt;&lt;img style="border-width: 0px; display: inline;" title="PinWorking" alt="PinWorking" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/ApplicationthatwontPintoTaskbarinWindows_135AC/PinWorking_21a19184-e780-458a-a313-afb1983c44fa.png" width="258" border="0" height="131"&gt; &lt;/p&gt;  &lt;p&gt;I also have this application hooked to a shortcut on the desktop and the desktop shortcut also doesn’t have a Pin to taskbar option like all other icons.&lt;/p&gt;  &lt;p&gt;As far as I know there’s nothing particularly special about this application. It’s an EXE launched from either a shortcut or directly from Explorer and it just will not pin. Since this is a distributed application I also installed it on another machine with exactly the same result. The context menu has no pinning options and I can drag the shortcut onto the taskbar either.&lt;/p&gt;  &lt;p&gt;This is an old FoxPro based application that uses the Visual FoxPro 9.0sp2 runtimes. Now some of you will jump on that and say “Aha!” – but that’s not it. I have several other applications that are configured pretty much in the same way – and they run fine and have perfectly fine pinning options. In fact the second screen shot you see is another FoxPro EXE application run off a shortcut. And it appears to be working just fine.&lt;/p&gt;  &lt;p&gt;So it appears it’s something inside the application that is causing this to occur. &lt;/p&gt;  &lt;h3&gt;It’s the Filename, Stupid!&lt;/h3&gt;  &lt;p&gt;So imagine that prior to this section I posted about 10 bullets of things I’d tried that didn’t work to solicit some feedback, when I ran across a Technet post with another guy who had an application named &lt;em&gt;documentation.exe&lt;/em&gt; that didn’t work. It was explained to him that there are a few ‘reserved’ words for EXE names that are treated special. &lt;em&gt;documenation.exe&lt;/em&gt; was a bad name – and bad names don’t get proper taskbar representation. Bad exe – go stand in the corner!&lt;/p&gt;  &lt;p&gt;Windows has a few reserved names that include things like Documentation, Help, Setup, Readme etc. that are not pinned to the taskbar. These are exceptions in Windows (sorry, I couldn’t find a link that provides a complete list).&lt;/p&gt;  &lt;p&gt;I dismissed that Technet post initially when I ran into it because the name of my EXE is pretty unique: wwhelp.exe. Not exactly a name you would expect to be on any sort of exception list. But it turns out the rules in Windows aren’t exact matches, but it looks for anything that &lt;strong&gt;contains &lt;/strong&gt;these names. So anything that contains the word Help in the EXE name is considered a special item (presumably a help file).&lt;/p&gt;  &lt;p&gt;So I renamed my file to HlpBuilder.exe and lo and behold – I get my Pin to taskbar back and all windows show up on the task context menu. It gets even better though. If I rename the EXE I do get the Pin to taskbar option, but if I create a shortcut and name it West Wind Html &lt;a href="http://www.west-wind.com/wwhelp/" target="top"&gt;Html Help Builder&lt;/a&gt; the shortcut again has no&amp;nbsp; Pin to taskbar option and I can’t drag it to the taskbar. Apparently if the reserved word appears in the text of the shortcut it too is limited in functionality.&lt;/p&gt;  &lt;h3&gt;Where is this Limitation coming from?&lt;/h3&gt;  &lt;p&gt;These ‘restricted’ values are determined by a registry key at:&lt;/p&gt;  &lt;p&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileAssociation\AddRemoveNames&lt;/p&gt;  &lt;p&gt;with these default values:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Documentation;Help;Install;More Info;Readme;Read me;Read First;Setup;Support;What's New;Remove&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="border: 0px none ; display: inline;" title="AddRemoveNames" alt="AddRemoveNames" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/ApplicationthatwontPintoTaskbarinWindows_135AC/AddRemoveNames_024fa269-ba4c-48ee-b102-a3e6b7429816.png" width="842" border="0" height="450"&gt; &lt;/p&gt;  &lt;p&gt;Man, how retarded is that? If an EXE file &lt;strong&gt;contains&lt;/strong&gt; any of these reserved words it won’t pin? If the Shortcut &lt;strong&gt;Text &lt;/strong&gt;contains one of these reserved words it won’t pin and generally work incorrectly? Really? Why have an arbitrary exception like that? That’s making an awful lot of assumptions and this is likely to break a number of application and they’re standard Windows behavior. This is an &lt;strong&gt;EPIC&lt;/strong&gt; design failure on Microsoft’s part.&lt;/p&gt;  &lt;p&gt;It looks like my only alternative is to rename the main EXE. I’m not really married to wwhelp.exe (how old skool of me – uh, this app is going on 15 years)Unfortunately it’s not quite as simple as that. There are update routines in a separate application that have the filename hard coded (and which doesn’t update at customers) and since the EXE is a COM server it needs to be re-registered. An EXE change basically requires a full reinstallation of the product instead of the normal update process I use.&amp;nbsp; But I don’t know what to do about the shortcut. I can’t just erase Help from the name of the shortcut since it’s the freaking product brand name.&lt;/p&gt;  &lt;p&gt;So as a vendor what do I do? Hack the registry during installation and modify that string, remove Help from the list? That’s evil mucking with user settings, but what other options are there?&lt;/p&gt;  &lt;p&gt;&amp;lt;sigh&amp;gt; It’s never easy on the Windows platform is it? How I hate building desktop apps these days, but this is one app that wouldn’t work well as a Web UI unfortunately.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=Vista'&gt;Vista&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=Windows'&gt;Windows&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f32765.aspx&amp;title=Application+that+won%26rsquo%3bt+Pin+to+Taskbar+in+Windows+7"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f32765.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=pvVDFJ3gbDc:jFaRFx1T1wE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=pvVDFJ3gbDc:jFaRFx1T1wE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=pvVDFJ3gbDc:jFaRFx1T1wE:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=pvVDFJ3gbDc:jFaRFx1T1wE:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=pvVDFJ3gbDc:jFaRFx1T1wE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=pvVDFJ3gbDc:jFaRFx1T1wE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=pvVDFJ3gbDc:jFaRFx1T1wE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=pvVDFJ3gbDc:jFaRFx1T1wE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=pvVDFJ3gbDc:jFaRFx1T1wE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/pvVDFJ3gbDc" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/32765.aspx</feedburner:origLink></item>
    <item>
      <title>Fun with Func&amp;lt;T,TResult&amp;gt; Delegates, Events and Async Operations</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/nrHBNV00i48/28442.aspx</link>
      <guid isPermaLink="false">28442_200910050838</guid>
      <pubDate>Mon, 05 Oct 2009 08:38:32 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/28442.aspx#Comments</comments>
      <slash:comments>15</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=28442</wfw:commentRss>
      <category>CSharp</category>
      <category>LINQ</category>
      <description>&lt;p&gt;Func&amp;lt;T&amp;gt; has been in .NET for a while, but with the arrival of LINQ it’s moved into the limelight as main performer that makes Lambda expressions work. Func&amp;lt;T&amp;gt; is basically a generic delegate that makes it extremely easy to create all sorts of custom delegate signatures without having to explicitly implement the delegates separately.&lt;/p&gt;  &lt;h3&gt;Events&lt;/h3&gt;  &lt;p&gt;How often have you lamented the fact that you have to create a custom delegate for an event that needs to fire a method that uses non-typical event arguments? Traditionally you had to create the method and also create a delegate that matched the signature which is a bit verbose at best. Typical event setup code looks something like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public event &lt;/span&gt;&lt;span style="color: #2b91af"&gt;&lt;strong&gt;delInvoiceCalculation&lt;/strong&gt; &lt;/span&gt;CalculateTax;
&lt;strong&gt;&lt;span style="color: blue"&gt;public delegate decimal &lt;/span&gt;&lt;span style="color: #2b91af"&gt;delInvoiceCalculation&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;wws_Invoice &lt;/span&gt;invoice);
&lt;/strong&gt;       
&lt;span style="color: blue"&gt;public virtual decimal &lt;/span&gt;OnCalculateTax(&lt;span style="color: #2b91af"&gt;wws_Invoice &lt;/span&gt;invoice)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;&lt;strong&gt;calcTax&lt;/strong&gt; = &lt;strong&gt;CalculateTax&lt;/strong&gt;;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;strong&gt;calcTax&lt;/strong&gt; != &lt;span style="color: blue"&gt;null&lt;/span&gt;)   
        &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;strong&gt;calcTax&lt;/strong&gt;(invoice);

    &lt;span style="color: blue"&gt;return &lt;/span&gt;invoice.Tax;
}&lt;/pre&gt;


&lt;p&gt;You have to declare a separate delegate and provide the appropriate signature to match the event function that should be called. &lt;/p&gt;

&lt;p&gt;Using Func&amp;lt;T&amp;gt; this code can be made a bit cleaner by removing the extra delegate. Here’s another implementation for a similar method using the same signature but using Func&amp;lt;T&amp;gt; or more specifically in this example, Func&amp;lt;T,TResult&amp;gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public event &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;wws_Invoice&lt;/span&gt;,&lt;span style="color: blue"&gt;decimal&lt;/span&gt;&amp;gt; CalculateHandling;
&lt;span style="color: blue"&gt;public virtual decimal &lt;/span&gt;OnCalculateHandling(&lt;span style="color: #2b91af"&gt;wws_Invoice &lt;/span&gt;invoice)
{
    &lt;span style="color: green"&gt;// TODO: provide logic here
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;calcHandling = CalculateHandling;
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(calcHandling != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        &lt;span style="color: blue"&gt;return &lt;/span&gt;calcHandling(invoice);

    &lt;span style="color: blue"&gt;return &lt;/span&gt;Entity.Handling;
}&lt;/pre&gt;


&lt;p&gt;Func&amp;lt;T&amp;gt; simplifies the event signature a bit by removing the explicit delegate declaration and instead using the generic Func&amp;lt;T,TResult&amp;gt; implementation that allows you to create a custom delegate signature directly on the event. Not only does it save a little bit of code typing, but I also find this easier to see what’s going because it is more explicit in a single statement compared the first snippet where delegate and event declaration are separate (and often completely separated physically because the delegate is reused by multiple events).&lt;/p&gt;

&lt;p&gt;Func&amp;lt;T&amp;gt; is a generic function signature/delegate and it works by implementing a delegate by way of its generic parameters. The last generic parameter provided is always the type of the return value (decimal above). Any preceeding generic parameters (up to 4 in Func&amp;lt;T&amp;gt;’s overloads) become the types of input parameters. In this case my signature is for Func&amp;lt;T,TResult&amp;gt; where T is my invoice entity and TResult is bool.&lt;/p&gt;

&lt;p&gt;In this respect:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;wws_Invoice&lt;/span&gt;,&lt;span style="color: blue"&gt;decimal&lt;/span&gt;&amp;gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;is equivalent to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;public delegate decimal &lt;/span&gt;&lt;span style="color: rgb(43,145,175)"&gt;delInvoiceCalculation&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;wws_Invoice &lt;/span&gt;invoice); &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;except it doesn’t have to be explicitly declared.&lt;/p&gt;

&lt;h3&gt;Func&amp;lt;T&amp;gt; in LINQ&lt;/h3&gt;

&lt;p&gt;Delegates are generally easy to understand but it’s one of those features we don’t use all that often and so it’s easy to forget how they work and what we need them for. Well we know LINQ is full of them – most LINQ operators like .Where() and OrderBy() and Select() to name a few all rely on Func&amp;lt;T&amp;gt; signatures for Lambda expressions. Between Func&amp;lt;T&amp;gt; delegate signatures and lamda expressions statements like this:&lt;/p&gt;

&lt;pre class="code"&gt;Context.wws_Items.Where( itm =&amp;gt; itm.Sku == sku );&lt;/pre&gt;


&lt;p&gt;become possible and quite readable once you get over the initial weirdness of the =&amp;gt; operator. What you’re looking at in the Where clause is actually an implemenation of Func&amp;lt;T,bool&amp;gt;:&lt;/p&gt;

&lt;p&gt;.&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="FuncTWhere" border="0" alt="FuncTWhere" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/FunwithFuncTTResultandDelegatesandEvents_369/FuncTWhere_74a253ec-3547-4aca-8484-f89182d1e419.png" width="688" height="115" /&gt; &lt;/p&gt;

&lt;p&gt;The input parameter is the the enumerable type (wws_Item from the List&amp;lt;wws_Item&amp;gt; and the return value is bool. The return value is inferred by the compiler and so only the input parameter is used (itm =&amp;gt;) in the lambda expression’s left side. Func&amp;lt;T&amp;gt; is a key feature to make LINQ workable using terse code.&lt;/p&gt;

&lt;p&gt;Note that if you use LINQ to SQL or LINQ to Entities Func&amp;lt;T&amp;gt; based parameters to any LINQ commands require an Expression wrapper that wraps the Func&amp;lt;T&amp;gt; expression. This is because these tools delay executing the expressions until a later point in time when the expressions are parsed into some other format (SQL command, Entity SQL or whatever the expression engine uses).&lt;/p&gt;

&lt;p&gt;This actually tripped me up yesterday and was what got me on to writing up this content. In my business layer I have basic CRUD operations including the ability to load entities without running a full LINQ command. There’s a base implementation that takes a LINQ expression as a parameter that is passed to a LINQ .Where() method that executes the actual query. At first I passed a Func&amp;lt;T&amp;gt; argument but I quickly found out that this doesn’t actually work – the result from the LINQ to SQL query always returned null. The reason: It’s not an expression that was passed but just a predicate.&lt;/p&gt;

&lt;p&gt;I had to make sure the method was declared correctly using an Expression and the correct code that works looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;protected virtual &lt;/span&gt;TEntity LoadBase(&lt;strong&gt;&lt;span style="color: rgb(43,145,175)"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;TEntity, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; whereClauseLambda&lt;/strong&gt;)
{
    SetError();

    &lt;span style="color: blue"&gt;try
    &lt;/span&gt;{
        TContext context = Context;

        &lt;span style="color: green"&gt;// If disconnected we'll create a new context
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Options.TrackingMode == &lt;span style="color: rgb(43,145,175)"&gt;TrackingMode&lt;/span&gt;.Disconnected)
            context = CreateContext();

        Entity = Context.GetTable&amp;lt;TEntity&amp;gt;().Where(&lt;strong&gt;whereClauseLambda&lt;/strong&gt;).SingleOrDefault();

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(Entity != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            OnLoaded(Entity);                

        &lt;span style="color: blue"&gt;return &lt;/span&gt;Entity;
    }
    &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;InvalidOperationException&lt;/span&gt;)
    {
        &lt;span style="color: green"&gt;// Handles errors where an invalid Id was passed, but SQL is valid
        &lt;/span&gt;SetError(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;Couldn't load entity - invalid key provided.&amp;quot;&lt;/span&gt;);
        Entity = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
        &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
    }
    &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;Exception &lt;/span&gt;ex)
    {
        &lt;span style="color: green"&gt;// handles any other sql errors                
        &lt;/span&gt;Entity = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
        SetError(ex);
    }

    &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;


&lt;h3&gt;&lt;/h3&gt;

&lt;p&gt;This makes it super easy to create custom load methods that all use the common LoadBase method and so inherit its behavior. in most cases it becomes as trivial as this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Loads an individual item by sku
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;sku&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43,145,175)"&gt;wws_Item &lt;/span&gt;LoadBySku(&lt;span style="color: blue"&gt;string &lt;/span&gt;sku)
{
    &lt;span style="color: blue"&gt;return this&lt;/span&gt;.LoadBase(itm =&amp;gt; itm.Sku == sku);
}&lt;/pre&gt;


&lt;p&gt;which is pretty nice and consistent.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;Easy Async&lt;/h3&gt;

&lt;p&gt;Here’s another useful example of how Func&amp;lt;T&amp;gt; can make life a lot easier. For example, kicking off an async delegate with Func&amp;lt;T&amp;gt; becomes a single line operation which makes it a snap to turn just about any operation into an async operation like this async update routine:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;LogSnippetViewAsync(&lt;span style="color: blue"&gt;string &lt;/span&gt;snippetId, &lt;span style="color: blue"&gt;string &lt;/span&gt;ipAddress, &lt;span style="color: blue"&gt;string &lt;/span&gt;userAgent)
{
&lt;strong&gt;    &lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt; del = &lt;span style="color: blue"&gt;this&lt;/span&gt;.LogSnippetView;
    del.BeginInvoke(snippetId, ipAddress, userAgent, &lt;span style="color: blue"&gt;null&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;);&lt;/strong&gt;
}

&lt;span style="color: blue"&gt;public bool &lt;/span&gt;LogSnippetView(&lt;span style="color: blue"&gt;string &lt;/span&gt;snippetId, &lt;span style="color: blue"&gt;string &lt;/span&gt;ipAddress, &lt;span style="color: blue"&gt;string &lt;/span&gt;userAgent)
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(userAgent))
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;

    userAgent = userAgent.ToLower();

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!(userAgent.Contains(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;mozilla&amp;quot;&lt;/span&gt;) || !userAgent.StartsWith(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;safari&amp;quot;&lt;/span&gt;) ||
        !userAgent.StartsWith(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;blackberry&amp;quot;&lt;/span&gt;) || !userAgent.StartsWith(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;t-mobile&amp;quot;&lt;/span&gt;) ||
        !userAgent.StartsWith(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;htc&amp;quot;&lt;/span&gt;) || !userAgent.StartsWith(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;opera&amp;quot;&lt;/span&gt;)))
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;

    &lt;span style="color: blue"&gt;this&lt;/span&gt;.Context.LogSnippetClick(snippetId, ipAddress); &lt;span style="color: green"&gt;// stored proc

    &lt;/span&gt;&lt;span style="color: blue"&gt;return true&lt;/span&gt;;
}&lt;/pre&gt;


&lt;p&gt;Here’s Func&amp;lt;T1,T2,T3,TResult&amp;gt; is used to specify 3 parameters (3 strings) and a return value of bool. del is the Delegate declaration and we’re pointing it at the LogSnippetView method to execute. Then BeginInvoke is called to asynchronously launch the method so it runs in the background on a thread pool thread.&lt;/p&gt;

&lt;p&gt;Again, using Func&amp;lt;T&amp;gt; avoids having to explicitly declare a delegate separately and instead you can directly declare the delegate signature via Func&amp;lt;T&amp;gt; inline which is easier to read and understand – at least to me.&lt;/p&gt;

&lt;p&gt;Sometimes it’s the little things that make life easier and Func&amp;lt;T&amp;gt; is one of those. &lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=CSharp'&gt;CSharp&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=LINQ'&gt;LINQ&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f28442.aspx&amp;title=Fun+with+Func%26lt%3bT%2cTResult%26gt%3b+Delegates%2c+Events+and+Async+Operations"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f28442.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=nrHBNV00i48:IPcuiBZ1x9g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=nrHBNV00i48:IPcuiBZ1x9g:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=nrHBNV00i48:IPcuiBZ1x9g:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=nrHBNV00i48:IPcuiBZ1x9g:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=nrHBNV00i48:IPcuiBZ1x9g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=nrHBNV00i48:IPcuiBZ1x9g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=nrHBNV00i48:IPcuiBZ1x9g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=nrHBNV00i48:IPcuiBZ1x9g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=nrHBNV00i48:IPcuiBZ1x9g:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/nrHBNV00i48" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/28442.aspx</feedburner:origLink></item>
    <item>
      <title>Lookbehind in Regex searches</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/_phvT6uGHYY/25208.aspx</link>
      <guid isPermaLink="false">25208_200910030903</guid>
      <pubDate>Sat, 03 Oct 2009 09:03:20 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/25208.aspx#Comments</comments>
      <slash:comments>11</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=25208</wfw:commentRss>
      <category>CSharp</category>
      <category>RegEx</category>
      <description>&lt;p&gt;I’ve said it before – Regex is not one of my strengths and although I use Regex expression quite frequently in code I’m in fear (literally) of using longer Regex expressions, fully expecting to look at my own Regex code and not remember what it does10 minutes later :-}. Ok, not quite so bad, but not completely off the mark.&lt;/p&gt;  &lt;p&gt;Today I had what is a fairly simple problem – I needed to match a JSON string and check for invalid quote characters in the string. For example:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;JSON String: \&amp;quot;that has legal nested quotes\&amp;quot; and &amp;quot;illegal nested quotes&amp;quot; embedded in it&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="1" face="verd"&gt;(leading and ending JSON quote marks are trimmed out prior to matching)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Basically what I needed to do is match the quotes around the illegal string to determine if the string is invalid JSON. This is somewhat tricky because the rule is to basically find double-quote characters that are NOT preceded by a slash.&lt;/p&gt;  &lt;p&gt;The solution to this is quite easy – once you know about a feature called Lookbehind – that basically lets you match or not match a group and not include the content in the match expression. Lookbehind uses (?&amp;lt;=) to match or&amp;#160; (?&amp;lt;!) expression followed by actual text or Regex values to match inside of the parenthesis. The negating Lookbehind&amp;#160; basically allows you to find a string if the lookbehind expression is NOT found. Exactly what I need above for my JSON string – I need to match all qutoes that are NOT preceeded by a slash.&lt;/p&gt;  &lt;p&gt;Using Lookbehind the solution to matching the illegal quotes is as simple as:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;($&amp;lt;!\\)&amp;quot;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Ah the beauty of terseness. Nice and self-describing, n’est pas? NOT. Here’s a more visual view in &lt;a href="http://www.regexbuddy.com/" target="_blank"&gt;RegexBuddy&lt;/a&gt; which is my preferred tool for Regex testing:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="RegExBuddy" border="0" alt="RegExBuddy" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/LookbehindinRegExsearches_14304/RegExBuddy_1cca467f-8014-4822-98cf-84f9be78ef22.png" width="684" height="501" /&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;As you can see the the legal quotes preceded by the slashes are not matched which is as it should be.&lt;/p&gt;  &lt;p&gt;In my .NET code that parses a JSON string (as part of full JSON parser) here’s the routine that uses the Regex expression:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Regex &lt;/span&gt;FindUnquotedStringRegEx = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Regex&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@&amp;quot;(?&amp;lt;!\\)&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;);

&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Parses a JSON string into a string value
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;value&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public string &lt;/span&gt;ParseString(&lt;span style="color: blue"&gt;string &lt;/span&gt;value)
{                                    
    &lt;span style="color: green"&gt;// actual value of null is not valid for 
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(value == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Resources&lt;/span&gt;.ERROR_INVALID_JSON_STRING);

    &lt;span style="color: green"&gt;// null as a string is a valid value for a string
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(value == &lt;span style="color: #a31515"&gt;&amp;quot;null&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;return null&lt;/span&gt;; 
    
    &lt;span style="color: green"&gt;// Has to be at least 2 chars long and bracketed in quotes
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(value.Length &amp;lt; 2 || (!value.StartsWith(&lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;) || !value.EndsWith(&lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;)))
        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Resources&lt;/span&gt;.ERROR_INVALID_JSON_STRING);
    
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(value == &lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;return string&lt;/span&gt;.Empty;
    
    &lt;span style="color: green"&gt;// strip off leading and trailing quote chars
    &lt;/span&gt;value = value.Substring(1, value.Length - 2);
    
    &lt;span style="color: green"&gt;// Check for strings NOT preceeded by a backslah - invalid
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(FindUnquotedStringRegEx.IsMatch(value))
        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Resources&lt;/span&gt;.ERROR_INVALID_JSON_STRING);

    &lt;span style="color: green"&gt;// Escape the double escape characters in json ('real' backslash)  temporarily to alternate chars
    &lt;/span&gt;&lt;span style="color: blue"&gt;const string &lt;/span&gt;ESCAPE_ESCAPECHARS = &lt;span style="color: #a31515"&gt;@&amp;quot;^#^#&amp;quot;&lt;/span&gt;;

    value = value.Replace(&lt;span style="color: #a31515"&gt;@&amp;quot;\\&amp;quot;&lt;/span&gt;, ESCAPE_ESCAPECHARS);

    value = value.Replace(&lt;span style="color: #a31515"&gt;@&amp;quot;\r&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;\r&amp;quot;&lt;/span&gt;);
    value = value.Replace(&lt;span style="color: #a31515"&gt;@&amp;quot;\n&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;);
    value = value.Replace(&lt;span style="color: #a31515"&gt;@&amp;quot;\&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;);            
    value = value.Replace(&lt;span style="color: #a31515"&gt;@&amp;quot;\t&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;\t&amp;quot;&lt;/span&gt;);
    value = value.Replace(&lt;span style="color: #a31515"&gt;@&amp;quot;\b&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;\b&amp;quot;&lt;/span&gt;);
    value = value.Replace(&lt;span style="color: #a31515"&gt;@&amp;quot;\f&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;\f&amp;quot;&lt;/span&gt;);

    &lt;span style="color: blue"&gt;if &lt;/span&gt;(value.Contains(&lt;span style="color: #a31515"&gt;&amp;quot;\\u&amp;quot;&lt;/span&gt;))
        value = &lt;span style="color: #2b91af"&gt;Regex&lt;/span&gt;.Replace(value, &lt;span style="color: #a31515"&gt;@&amp;quot;\\u....&amp;quot;&lt;/span&gt;,
                              &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MatchEvaluator&lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.UnicodeEscapeMatchEvaluator));

    &lt;span style="color: green"&gt;// Convert escaped characters back to the actual backslash char 
    &lt;/span&gt;value = value.Replace(ESCAPE_ESCAPECHARS, &lt;span style="color: #a31515"&gt;&amp;quot;\\&amp;quot;&lt;/span&gt;);

    &lt;span style="color: blue"&gt;return &lt;/span&gt;value;
}&lt;/pre&gt;


&lt;p&gt;And it works.&lt;/p&gt;

&lt;p&gt;I’ve never really used Lookbehind before (gulp) and when I popped out a question regarding the matches I was looking for earlier today on &lt;a href="http://twitter.com/rickstrahl" target="_blank"&gt;Twitter&lt;/a&gt; several folks were very helpful in pointing me in the right direction. Thanks to &lt;a href="http://twitter.com/lumbarius/"&gt;lumbarius&lt;/a&gt; who got the expression and a link to find out more.&lt;/p&gt;

&lt;p&gt;I dug out my trusty copy of &lt;a href="http://www.amazon.com/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124%3FSubscriptionId%3D1SDRSQH20CF1ZSXE6Y02%26tag%3Dwestwindtechn-20%26linkCode%3Dsp1%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596528124" target="_blank"&gt;O’Reilly’s Mastering RegEx Expressions&lt;/a&gt; out today and did a little more reading on the topic.&lt;/p&gt;

&lt;p&gt;
  &lt;table cellpadding="5"&gt;&lt;tbody&gt;
      &lt;tr&gt;
        &lt;td valign="top"&gt;&lt;img border="1" src="http://ecx.images-amazon.com/images/I/41Hl9UQ6IuL._SL160_.jpg" /&gt;&lt;/td&gt;

        &lt;td valign="top"&gt;&lt;b&gt;Mastering Regular Expressions&lt;/b&gt; 

          &lt;br /&gt;by Jeffrey Friedl 

          &lt;br /&gt;&lt;small&gt;O'Reilly Media, Inc. (August 8, 2006)&lt;/small&gt; 

          &lt;br /&gt;

          &lt;br /&gt;&lt;a href="http://www.amazon.com/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124%3FSubscriptionId%3D1SDRSQH20CF1ZSXE6Y02%26tag%3Dwestwindtechn-20%26linkCode%3Dsp1%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596528124" target="_blank"&gt;Read more...&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;&lt;/table&gt;
&lt;/p&gt;

&lt;p&gt;I’ve certainly read through that section on Lookahead and Lookbehind before but at the time it really didn’t mean much and certainly didn’t sink in, but now with a little context behind it I think… I think… I can maybe retain this for more than 10 minutes. And if not I have this blog post to help me remember. If I can remember the blog post – Arrgh… where does it stop? &lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category=CSharp'&gt;CSharp&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=RegEx'&gt;RegEx&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f25208.aspx&amp;title=Lookbehind+in+Regex+searches"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f25208.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_phvT6uGHYY:969FWFlpaVA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_phvT6uGHYY:969FWFlpaVA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_phvT6uGHYY:969FWFlpaVA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=_phvT6uGHYY:969FWFlpaVA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_phvT6uGHYY:969FWFlpaVA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=_phvT6uGHYY:969FWFlpaVA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_phvT6uGHYY:969FWFlpaVA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=_phvT6uGHYY:969FWFlpaVA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=_phvT6uGHYY:969FWFlpaVA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/_phvT6uGHYY" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/25208.aspx</feedburner:origLink></item>
    <item>
      <title>Debugger Visualizers not working in ASP.NET Medium Trust</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/Sa_xd3j1H44/13494.aspx</link>
      <guid isPermaLink="false">13494_200909240748</guid>
      <pubDate>Thu, 24 Sep 2009 07:48:07 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/13494.aspx#Comments</comments>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=13494</wfw:commentRss>
      <category> ASP.NET</category>
      <category> Visual Studio</category>
      <description>&lt;p&gt; So imagine you are running your ASP.NET application’s in medium trust and you want to access a debugger visualizer like this:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="VisualizeThis" border="0" alt="VisualizeThis" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/DebuggerVisualizersnotwor.NETMediumTrust_DB98/VisualizeThis_949ad515-199d-4539-a4f4-dc87a8943f8b.png" width="603" height="150" /&gt; &lt;/p&gt;  &lt;p&gt;by clicking on the little search icon in the debugger tooltip, you run into a message like this:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;The application you are debugging has insufficient privileges to allow the use of custom visualizers&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;or more visually here failing with a DataTable visualizer:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DebuggerVisualizerAspNet" border="0" alt="DebuggerVisualizerAspNet" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/DebuggerVisualizersnotwor.NETMediumTrust_DB98/DebuggerVisualizerAspNet_c21c5161-b644-4e40-825d-77ea977bdc98.png" width="750" height="503" /&gt; &lt;/p&gt;  &lt;p&gt;Ah yes, see the documentation. I know I should have read that &lt;strong&gt;one page pamphlet&lt;/strong&gt; Microsoft ships for documentation with ASP.NET. Right.&lt;/p&gt;  &lt;p&gt;The problem is that the application needs to run in Full trust in order to use debugger visualizers. This can be changed in Web.config by making sure that the &lt;strong&gt;trust&lt;/strong&gt; key :&lt;/p&gt;  &lt;pre class="code"&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.web&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;trust &lt;/span&gt;&lt;span style="color: red"&gt;level&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Full&lt;/span&gt;&amp;quot; &lt;/strong&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.web&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: blue"&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt; &lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;&lt;/p&gt;

&lt;p&gt;is set to Full trust.&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DebuggerVisualizer" border="0" alt="DebuggerVisualizer" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/DebuggerVisualizersnotwor.NETMediumTrust_DB98/DebuggerVisualizer_a9b41837-a19c-43bb-868c-cf8771b56cc8.png" width="857" height="569" /&gt; &lt;/p&gt;

&lt;p&gt;Debugger visualizers can come from many sources so the security environment for the visualizers is different than than main debugger and as such it requires explicit permissions to execute. &lt;/p&gt;

&lt;p&gt;Be careful with these settings though. For production sites it’s recommended you run in Medium trust, so if you change settings in your local config file remember not to send them up to the server. Better yet, change the settings only while you need it for debugging and then set it back.&lt;/p&gt;

&lt;p&gt;I run into this frequently because I try to set up my Web sites during development with Medium trust if I can to see all the places when and if I run into problems. So I often end up having to change that switch temporarily for debugging and then setting it back when I’m done with this task.&lt;/p&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category= ASP.NET'&gt; ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category= Visual Studio'&gt; Visual Studio&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f13494.aspx&amp;title=Debugger+Visualizers+not+working+in+ASP.NET+Medium+Trust"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f13494.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Sa_xd3j1H44:LEpJ-gsVVuU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Sa_xd3j1H44:LEpJ-gsVVuU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Sa_xd3j1H44:LEpJ-gsVVuU:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Sa_xd3j1H44:LEpJ-gsVVuU:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Sa_xd3j1H44:LEpJ-gsVVuU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Sa_xd3j1H44:LEpJ-gsVVuU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Sa_xd3j1H44:LEpJ-gsVVuU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Sa_xd3j1H44:LEpJ-gsVVuU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Sa_xd3j1H44:LEpJ-gsVVuU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/Sa_xd3j1H44" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/13494.aspx</feedburner:origLink></item>
    <item>
      <title>Integrating OpenID in an ASP.NET MVC Application using DotNetOpenAuth</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/iWRtB-LxKJ8/899303.aspx</link>
      <guid isPermaLink="false">899303_200909180415</guid>
      <pubDate>Fri, 18 Sep 2009 04:15:24 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/899303.aspx#Comments</comments>
      <slash:comments>23</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=899303</wfw:commentRss>
      <category> ASP.NET</category>
      <category>MVC</category>
      <description>&lt;p&gt;The #1 request I got on the &lt;a href="http://codepaste.net/"&gt;CodePaste.net&lt;/a&gt; site - which provides a quick and easy way to publish and share code snippets publicly - has been to implement OpenId for authentication rather than the custom username/password login that’s been in use up until now. OpenId is a centralized login/authentication mechanism which handles authentication through one or more centralized OpenId providers. These providers live on the Web and are accessed through a forwarding and callback mechanism – you log in at the provider’s site and are then returned to the original starting Url with an authorized user token that uniquely identifies that user to the original site. &lt;/p&gt;  &lt;h3&gt;What is OpenId?&lt;/h3&gt;  &lt;p&gt;OpenId is a single sign-on scheme – the idea is that you keep your login and profile information in one place so that you don’t have to login at every Web location and create new user credentials on each site. The&amp;#160; idea of a single sign on isn’t new of course – lots of these things have been around over the years with the most remembered probably being Microsoft’s Passport/Windows Live ID (not that anybody likes Windows Live Id). OpenId uses a similar concept, but the difference is that there are many providers and&amp;#160; sites that are implementing OpenId Providers so that you can use their log on credentials that you are already using to log into other sites. Chances are that you already have a sign on on one of the OpenId providers rather than just one provider that controls access. You can essentially choose where you log in from.Some of sites that are OpenId providers now are Google, Yahoo, Microsoft Windows Live, AOL, Facebook, Flickr and many many more. Chances are you’re signed up on one of these services and you can use their logons to log in to other sites that support OpenId. The rush to OpenId is fairly fresh so some of these work better than others. The ones I’ve been using are MyOpenId, Google and Yahoo of which MyOpenId works best if you want to share profile information.&lt;/p&gt;  &lt;p&gt;To be honest I hadn’t warmed up to OpenId until recently. In fact I had to be convinced by user requests on the CodePaste.net site to take a look at integration. Now that it’s there I think it is a pretty sweet way to go although I think the concept is lost on the average user until OpenId becomes more wide spread. It also didn’t help that the original implementations and providers were pretty crappy and the process on most sites to sign up actually was really slow and clunky. That has changed a bit with better interfaces that are faster and many more sites are using OpenId and many more providers exist. &lt;/p&gt;  &lt;p&gt;Another pain point is that supporting standards for retrieving profile information like Simple Registration (SREG) is not widely supported. Providers are returning information in a variety of different formats and most don’t return profile information at all whether you approve or not which is really lame. You presumably own the data on any service you’ve given data to so why the fuss of sharing it if you approve of sharing? Anyway, don’t count on getting full contact information from OpenId for a while. Some providers will give some information, others won’t give any – so your application has to be able to handle both scenarios.&lt;/p&gt;  &lt;h3&gt;OpenId Development&lt;/h3&gt;  &lt;p&gt;For development with .NET there are a few libraries out there that handle the communications details for you. While communications are handled using simple URLs for routing and callbacks the data encoded into these URLs must be secure so that they can’t be spoofed and this process is not exactly trivial.&lt;/p&gt;  &lt;p&gt;For the site I chose &lt;a href="http://dotnetopenauth.net:8000/"&gt;DotNetOpenAuth&lt;/a&gt; – after doing a little bit of research it seemed to me that this was the most active development project that is also most feature rich. DotNetOpenAuth does much more than OpenId it also supports oAuth (a non-interactive service based counterpart to OpenId) which is another thing on my list to implement for the API portion of the site. DotNetOpenAuth&amp;#160; is fairly comprehensive and includes support specifically for Web applications – both MVC and Web Forms with controls and helpers provided as well as MVC specific action methods to handle redirection and return routing which is a nice touch.&lt;/p&gt;  &lt;p&gt;The tool makes the actual routing and handling of the results fairly easy, but the integration process nevertheless is not completely trivial. The reason for this is that most applications will need to handle both logins as well as attaching an OpenId account to an existing user profile of some sort and this can get tricky because of the HTTP GET based callback interface. The actual OpenId calls and callbacks are quite simple – the actual user interface and hookup routines though ended up taking me a lot longer than I had expected.&lt;/p&gt;  &lt;h3&gt;Walking through OpenId Authentication&lt;/h3&gt;  &lt;p&gt;Alright lets take a look and see how this works on the CodePaste.net site. As I mentioned there are two parts – the basic login validation which is very straight forward and simple so I’ll start there. &lt;/p&gt;  &lt;p&gt;The login form displays both logins for OpenId and the traditional username and password:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/ImplementingOpenIDinan.NETMVCApplication_E99/OpenIdLogin_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="OpenIdLogin" border="0" alt="OpenIdLogin" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/ImplementingOpenIDinan.NETMVCApplication_E99/OpenIdLogin_thumb.png" width="700" height="477" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Figure 1 – Logging in with OpenId&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I needed to leave the old login in form place so existing users can log in and attach their existing accounts to OpenId. Also some folks may just not want to go the OpenId route. So both are supported on this form.&lt;/p&gt;  &lt;p&gt;OpenId validation starts by providing a OpenId Url. The Url depends on the provider and you can pick up that Url from your provider’s OpenId information page – &lt;a href="http://openid.net/get-an-openid/"&gt;here is a list of a few common ones from the OpenId site&lt;/a&gt;. I also provided a couple of icon buttons for the most likely culprits – MyOpenId, Google and Yahoo. Any others need to be typed in. Between Google and Yahoo you probably have an account. There’s also myOpenId which is one of the early providers which is popular, and with it you use a url like &lt;a href="http://rickstrahl.myopenid.com"&gt;http://rickstrahl.myopenid.com&lt;/a&gt; to log on. The Yahoo (&lt;a href="http://yahoo.com/"&gt;http://yahoo.com/&lt;/a&gt;) and Google (&lt;a title="https://www.google.com/accounts/o8/id" href="https://www.google.com/accounts/o8/id"&gt;https://www.google.com/accounts/o8/id&lt;/a&gt;&lt;strong&gt;)&lt;/strong&gt; Urls are the same for everybody, so those links can actually be auto-fired directly by the click on the icon, while the myOpenId entry requires entering the name first and manually clicking the button.&lt;/p&gt;  &lt;p&gt;Once the Login button is clicked (or automatically fired) the process takes you to the provider’s site. For example if you use Google, you’ll see a Google Login screen if you aren’t already signed into Google and you are asked to login. The page will tell you the source site that’s requesting the login and possibly which profile information is requested. Once you log in you are then redirected hence you came – back to the same url where you came from by default. This can be overridden, but in an MVC application you’ll most likely will want to come back to the same URL to redisplay the login (or registration) data with some indication that you are now logged in. &lt;/p&gt;  &lt;p&gt;If you are already logged into the OpenId provider (which is usually the case) the login operation is completely transparent – the page is re-routed to the OpenId provider site and immediately returns back to your site at a Url that is specifed. This usually happens pretty fast through a bunch of redirects – from your site to the OpenId provider and fro the OpenId provider back to your site – so other than some extra delay time you don’t even see anything happening. It just looks like you’re going directly to your next page in the app.&lt;/p&gt;  &lt;p&gt;When the page returns after a login it includes encoded authentication information on the querystring that becomes available to the request that handles the OpenId login. Specifially DotNetOpenAuth can read the authentication token and any profile information that was returned if any was requested and returned. &lt;/p&gt;  &lt;p&gt;Once logged in my profile display then reflects the account association like this:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Loggedin" border="0" alt="Loggedin" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/ImplementingOpenIDinan.NETMVCApplication_E99/Loggedin_59e1e5e6-286c-433c-9f1e-2b7d5717aaa9.png" width="749" height="612" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Figure 2 – Logged in with OpenId and viewing the Profile&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The application stores the user’s open id as part of the profile and so it’s easy to display this information. The OpenId relationship can be unlinked and the account can then be assigned to another OpenId or a username and password has to be provided if no OpenId is available. As I mentioned the actual OpenId authentication process is pretty simple but some of the issues surrounding it like attaching and disconnecting accounts from OpenId is a little more complicated – I’ll talk about that below.&lt;/p&gt;  &lt;p&gt;If I go to the profile page when the account is not associated with an OpenId the page has an option to login and effectively associate the account with the new OpenId:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Registration" border="0" alt="Registration" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/ImplementingOpenIDinan.NETMVCApplication_E99/Registration_571db2fa-978d-4adc-aa68-1bf427ac2dc7.png" width="750" height="647" /&gt; &lt;/p&gt;  &lt;p&gt;The same page is also used for new registrations which is useful in order to provide the name and email actually from the OpenId provider (as supported – note that google and yahoo do not provide this data in a format that DotnetOpenAuth extracts automatically).&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;How to implement OpenId in an MVC Application&lt;/h3&gt;  &lt;p&gt;Please keep in mind that what I describe is just one way you can do this in this case using DotNetOpenAuth since it provides a host of different ways to implement OpenId. There are high level helpers and for Web Forms there is a server control that you can use. In this example I handle this process manually so you can see the flow of the requests. The process is pretty simple although there’s a fair bit of code (most of it boilerplate) that is involved.&lt;/p&gt;  &lt;p&gt;I’ll start with the sign in form because that’s simpler. This relates to figure 1 in the image sequence above. The OpenId login area of the page is wrapped into its own HTML form that kicks off the processing. The layout for this block looks like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;using &lt;/span&gt;(Html.BeginForm(&lt;span style="color: blue"&gt;new &lt;/span&gt;{ Controller=&lt;span style="color: #a31515"&gt;&amp;quot;Account&amp;quot;&lt;/span&gt;,Action=&lt;span style="color: #a31515"&gt;&amp;quot;OpenIdLogon&amp;quot; &lt;/span&gt;}))
       { &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;         
         &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;fieldset &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;                             
         &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;containercontent&amp;quot; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
             &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;labelheaderblock&amp;quot;&amp;gt;&lt;/span&gt;Log on using OpenId:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
             &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openid_identifier&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openid_identifier&amp;quot;/&amp;gt;             
             &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btnOpenIdLogin&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;submit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Login&amp;quot;/&amp;gt;        
             &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;imgOpenIdLoginProgress&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/css/images/loading_small.gif&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;display&lt;/span&gt;:&lt;span style="color: blue"&gt;none&amp;quot; /&amp;gt;                 
             
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;divOpenIdIcons&amp;quot;&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/images/openid-icon.png&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openIdUrl('openid')&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myopenid.com&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hoverbutton&amp;quot; /&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/images/google-icon.png&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openIdUrl('google')&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Google&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hoverbutton&amp;quot;/&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/images/yahoo-icon.png&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openIdUrl('yahoo')&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Yahoo&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hoverbutton&amp;quot; /&amp;gt;
             &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;     
         &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
         &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;fieldset&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;   &lt;/pre&gt;


&lt;p&gt;The image icons fire a small JavaScript routine that creates the OpenId urls that are injected into the text box:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;openIdUrl(site)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;value = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;autoClick = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
    
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(site == &lt;span style="color: #a31515"&gt;&amp;quot;openid&amp;quot;&lt;/span&gt;) {
        value = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;lt;Your Account&amp;gt;.myopenid.com&amp;quot;
    &lt;/span&gt;}
    &lt;span style="color: blue"&gt;else if &lt;/span&gt;(site == &lt;span style="color: #a31515"&gt;&amp;quot;google&amp;quot;&lt;/span&gt;) {
        value = &lt;span style="color: #a31515"&gt;&amp;quot;https://www.google.com/accounts/o8/id&amp;quot;&lt;/span&gt;;
        autoClick = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
    }
    &lt;span style="color: blue"&gt;else if &lt;/span&gt;(site == &lt;span style="color: #a31515"&gt;&amp;quot;yahoo&amp;quot;&lt;/span&gt;) {
        value = &lt;span style="color: #a31515"&gt;&amp;quot;http://yahoo.com/&amp;quot;
        &lt;/span&gt;autoClick = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
    }
        
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(value) {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;jText = $(&lt;span style="color: #a31515"&gt;&amp;quot;#openid_identifier&amp;quot;&lt;/span&gt;);
       jText.val(value)
            .focus();
       &lt;span style="color: blue"&gt;if &lt;/span&gt;(autoClick)
           $(&lt;span style="color: #a31515"&gt;&amp;quot;#btnOpenIdLogin&amp;quot;&lt;/span&gt;).trigger(&lt;span style="color: #a31515"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;);
    }       
}&lt;/pre&gt;


&lt;p&gt;You can add to this with other URLs and icons as you see fit. I stuck with those three because they are the most common that people will have accounts on but that may change. All others OpenId Urls can be typed in by hand (which is not so smooth).&lt;/p&gt;

&lt;p&gt;When the Login button is clicked and the request is submitted it fires into an OpenIdLogOn action method of the controller. The controller has to accept both POST and GET operations. POST is from the initial button click, the GET will occur when the OpenId provider fires back the response and provides the data via the query string.&lt;/p&gt;

&lt;p&gt;As mentioned I’m using DotNetOpenAuth here which is a single large DLL you can drop into your BIN folder. It handles all the heavy lifting of creating the redirect link and cracking the response query string extracting the authentication token.&lt;/p&gt;

&lt;p&gt;The process involves two steps: Making the original request to the OpenId provider (which redirects) and handling the response that comes back. Here’s the code (which is pretty close to the sample code provided in one of the demos):&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;AcceptVerbs&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;HttpVerbs&lt;/span&gt;.Post | &lt;span style="color: #2b91af"&gt;HttpVerbs&lt;/span&gt;.Get), &lt;span style="color: #2b91af"&gt;ValidateInput&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;)]
&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;OpenIdLogOn(&lt;span style="color: blue"&gt;string &lt;/span&gt;returnUrl)
{
&lt;strong&gt;    &lt;span style="color: blue"&gt;var &lt;/span&gt;openid = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OpenIdRelyingParty&lt;/span&gt;();
    &lt;span style="color: blue"&gt;var &lt;/span&gt;response = openid.GetResponse();&lt;/strong&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;if &lt;/span&gt;(response == &lt;span style="color: blue"&gt;null&lt;/span&gt;)  &lt;font color="#008000"&gt;// Initial operation&lt;/font&gt;
    {
        &lt;span style="color: green"&gt;// Step 1 - Send the request to the OpenId provider server
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Identifier &lt;/span&gt;id;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Identifier&lt;/span&gt;.TryParse(Request.Form[&lt;span style="color: #a31515"&gt;&amp;quot;openid_identifier&amp;quot;&lt;/span&gt;], &lt;span style="color: blue"&gt;out &lt;/span&gt;id))
        {
            &lt;span style="color: blue"&gt;try
            &lt;/span&gt;{
               &lt;strong&gt; &lt;span style="color: blue"&gt;var &lt;/span&gt;req = openid.CreateRequest(Request.Form[&lt;span style="color: #a31515"&gt;&amp;quot;openid_identifier&amp;quot;&lt;/span&gt;]);
                &lt;span style="color: blue"&gt;return &lt;/span&gt;req.RedirectingResponse.AsActionResult();&lt;/strong&gt;
            }
            &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ProtocolException &lt;/span&gt;ex)
            {
                &lt;span style="color: green"&gt;// display error by showing original LogOn view
                &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(&lt;span style="color: #a31515"&gt;&amp;quot;Unable to authenticate: &amp;quot; &lt;/span&gt;+ ex.Message);
                &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;Logon&amp;quot;&lt;/span&gt;,&lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
            }
        }
        &lt;span style="color: blue"&gt;else
        &lt;/span&gt;{
            &lt;span style="color: green"&gt;// display error by showing original LogOn view
            &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(&lt;span style="color: #a31515"&gt;&amp;quot;Invalid identifier&amp;quot;&lt;/span&gt;);
            &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;LogOn&amp;quot;&lt;/span&gt;,&lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
        }
    }
    &lt;span style="color: blue"&gt;else  &lt;font color="#008000"&gt;// OpenId redirection callback&lt;/font&gt;
    &lt;/span&gt;{
        &lt;span style="color: green"&gt;// Step 2: OpenID Provider sending assertion response
        &lt;/span&gt;&lt;span style="color: blue"&gt;switch &lt;/span&gt;(&lt;strong&gt;response.Status&lt;/strong&gt;)
        {
           &lt;strong&gt; &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AuthenticationStatus&lt;/span&gt;.Authenticated:&lt;/strong&gt;
                &lt;span style="color: blue"&gt;string &lt;/span&gt;identifier = &lt;strong&gt;response.ClaimedIdentifier&lt;/strong&gt;;

                &lt;span style="color: green"&gt;// OpenId lookup fails - Id doesn't exist for login - login first
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(busUser.ValidateUserOpenIdAndLoad(identifier) == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                {
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.HtmlEncodeMessage = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(busUser.ErrorMessage +
                            &lt;span style="color: #a31515"&gt;&amp;quot;Please &amp;lt;a href='&amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;WebUtils&lt;/span&gt;.ResolveUrl(&lt;span style="color: #a31515"&gt;&amp;quot;~/Account/Register&amp;quot;&lt;/span&gt;) +
                            &lt;span style="color: #a31515"&gt;&amp;quot;'&amp;gt;register&amp;lt;/a&amp;gt; to create a new account or &amp;lt;a href='&amp;quot; &lt;/span&gt;+
                            &lt;span style="color: #2b91af"&gt;WebUtils&lt;/span&gt;.ResolveUrl(&lt;span style="color: #a31515"&gt;&amp;quot;~/Account/Register&amp;quot;&lt;/span&gt;) +
                            &lt;span style="color: #a31515"&gt;&amp;quot;'&amp;gt;associate&amp;lt;/a&amp;gt; an existing account with your OpenId&amp;quot;&lt;/span&gt;);

                    &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;LogOn&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
                }

                &lt;span style="color: green"&gt;// Capture user information for AuthTicket
                // and issue Forms Auth token
                &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UserState &lt;/span&gt;userState = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UserState&lt;/span&gt;()
                {
                    Email = busUser.Entity.Email,
                    Name = busUser.Entity.Name,
                    UserId = busUser.Entity.Id,
                    IsAdmin = busUser.Entity.IsAdmin
                };
                &lt;strong&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.IssueAuthTicket(userState, &lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;/strong&gt;

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(returnUrl))
                    &lt;span style="color: blue"&gt;return &lt;/span&gt;Redirect(returnUrl);

                &lt;span style="color: blue"&gt;return &lt;/span&gt;Redirect(&lt;span style="color: #a31515"&gt;&amp;quot;~/new&amp;quot;&lt;/span&gt;);

            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AuthenticationStatus&lt;/span&gt;.Canceled:
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowMessage(&lt;span style="color: #a31515"&gt;&amp;quot;Canceled at provider&amp;quot;&lt;/span&gt;);
                &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;LogOn&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AuthenticationStatus&lt;/span&gt;.Failed:
                &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(response.Exception.Message);
                &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;LogOn&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
        }
    }
    &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EmptyResult&lt;/span&gt;();
}&lt;/pre&gt;


&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The code uses the &lt;em&gt;OpenIdRelyingParty&lt;/em&gt; class to handle the processing of the login. The first step occurs when the button is clicked and there’s no provider response to process. This code:&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;req = openid.CreateRequest(Request.Form[&lt;span style="color: #a31515"&gt;&amp;quot;openid_identifier&amp;quot;&lt;/span&gt;]); 

      &lt;br /&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;req.RedirectingResponse.AsActionResult();&lt;/font&gt;&lt;/font&gt; &lt;/p&gt;

&lt;p&gt;fires off the the request. The openid_identifier is the OpenId Url the user entered into the form and it’s passed to DotNetOpenAuth to start formulating a request for authentication at that Url.&lt;/p&gt;

&lt;p&gt;The code above starts the redirection sequence going to the provider and back to the current page&amp;#160; - since I didn’t specify another Url to return to by default the request returns to the current page’s url.&lt;/p&gt;

&lt;p&gt;As mentioned I’m using MVC so and as you can see DotNetOpenAuth conveniently includes an AsActionResult() method that creates redirect response in a proper MVC style response which is very thoughtful for consistency. You can also retrieve the URL directly and fire it on your own although I can’t see why you would. If you’re using WebForms or a handler there are other methods on RedirectingResponse to fire the redirects for you.&lt;/p&gt;

&lt;p&gt;Next the browser is redirected to the OpenId provider where you either are asked to log in or if you already are logged in you are authenticated and immediately returned to the current page. When the request returns it is now a GET operation and we start back out at the top of the same Controller action.&lt;/p&gt;

&lt;p&gt;This time around:&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;response = openid.GetResponse();&lt;/font&gt;&lt;/font&gt; &lt;/p&gt;

&lt;p&gt;will not be null – the return URL includes a bunch of new encoded querystring values. GetResponse() looks for those and based on that creates the response instance and the code can branch into the greater if block. The request will either be authenticated, canceled or failed. Failure can be any number of things such as invalid login information, or timing out or some sort of tampering with the URL. Both cancel and failure operations are handled by simply redisplaying the current view with an error message.&lt;/p&gt;

&lt;p&gt;If authentication succeeded we can retrieve a unique identifier that identifies the user’s provider choice and we’re guaranteed at this point that this user was authenticated through OpenId.&amp;#160; Yay!&lt;/p&gt;

&lt;p&gt;Although you now know the user is authenticated ASP.NET knows nothing about this authentication yet, so the next step is to set a FormsAuthentication ticket to authenticate the user to the application. This process is no different than doing a manual login in any other ASP.NET application with Forms Authentication. &lt;/p&gt;

&lt;p&gt;In CodePaste.net I store a user record in the ticket so I have some basic user information available to my application on each hit without having to use session storage or retrieving this info on every request from the database. The code does this:&lt;/p&gt;

&lt;pre class="code"&gt; &lt;span style="color: green"&gt;// Capture user information for AuthTicket
// and issue Forms Auth token
&lt;/span&gt;UserState userState = &lt;span style="color: blue"&gt;new &lt;/span&gt;UserState()
{
    Email = busUser.Entity.Email,
    Name = busUser.Entity.Name,
    UserId = busUser.Entity.Id,
    IsAdmin = busUser.Entity.IsAdmin
};
&lt;span style="color: blue"&gt;this&lt;/span&gt;.IssueAuthTicket(userState, &lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;/pre&gt;


&lt;p&gt;where IssueAuthTicket() looks like this doing standard Forms Authentication ticket assignment:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Issues an authentication issue from a userState instance
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;userState&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;rememberMe&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;IssueAuthTicket(&lt;span style="color: #2b91af"&gt;UserState &lt;/span&gt;userState,&lt;span style="color: blue"&gt;bool &lt;/span&gt;rememberMe)
{
    &lt;span style="color: #2b91af"&gt;FormsAuthenticationTicket &lt;/span&gt;ticket = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FormsAuthenticationTicket&lt;/span&gt;(1, userState.UserId,
                                                         &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now, &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddDays(10),
                                                         rememberMe, userState.ToString());

    &lt;span style="color: blue"&gt;string &lt;/span&gt;ticketString = &lt;span style="color: #2b91af"&gt;FormsAuthentication&lt;/span&gt;.Encrypt(ticket);
    &lt;span style="color: #2b91af"&gt;HttpCookie &lt;/span&gt;cookie = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HttpCookie&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;FormsAuthentication&lt;/span&gt;.FormsCookieName, ticketString);
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(rememberMe)
        cookie.Expires = &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.AddDays(10);

    HttpContext.Response.Cookies.Add(cookie);
}&lt;/pre&gt;

&lt;p&gt;Once the auth ticket’s been issued the application simply redirects to another page in the application (the new snippet page in this case). &lt;/p&gt;

&lt;p&gt;BTW just for clarfication, the userState object contains logic to easily persist to and from string so this object is easily retrieved at the beginning of a request and stored on updates. In my base controller I do: 
  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;protected override void &lt;/span&gt;Initialize(System.Web.Routing.&lt;span style="color: #2b91af"&gt;RequestContext &lt;/span&gt;requestContext)
{
    &lt;span style="color: blue"&gt;base&lt;/span&gt;.Initialize(requestContext);

    &lt;span style="color: green"&gt;// Grab the user's login information from FormsAuth
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UserState &lt;/span&gt;userState = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UserState&lt;/span&gt;();
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.User.Identity != &lt;span style="color: blue"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; &lt;span style="color: blue"&gt;this&lt;/span&gt;.User.Identity &lt;span style="color: blue"&gt;is &lt;/span&gt;&lt;span style="color: #2b91af"&gt;FormsIdentity&lt;/span&gt;)
        &lt;span style="color: blue"&gt;this&lt;/span&gt;.UserState.FromString(((&lt;span style="color: #2b91af"&gt;FormsIdentity&lt;/span&gt;)&lt;span style="color: blue"&gt;this&lt;/span&gt;.User.Identity).Ticket.UserData);

    &lt;span style="color: green"&gt;// have to explicitly add this so Master can see untyped value
    &lt;/span&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewData[&lt;span style="color: #a31515"&gt;&amp;quot;UserState&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;this&lt;/span&gt;.UserState;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewData[&lt;span style="color: #a31515"&gt;&amp;quot;ErrorDisplay&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay;
}&lt;/pre&gt;

&lt;p&gt;The process to authenticate using OpenId is pretty straight forward. No surprises here, really. All we need to have is some conditional logic to route for redirect initially and pick up the result when the request comes back and handle the authentication and creation of a new FormsAuthentication ticket. When the request returns and is marked as authenticated you can safely assume the user is valid. Because of the message encryption and timed security tokens the data is safe and not hijackable. &lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Registration – A little more complex&lt;/h3&gt;

&lt;p&gt;The log in process is straight forward primarily because the request doesn’t need to track data that is already on the page. You log in and you move on to another page. However in a log in form (Figure 3) there may be additional pieces of information that you need to track. More importantly you typically have some state associated with the registration page – like which user (or a new user) is currently being displayed and that information has to be carried forward when the Open Id request returns from the provider. So the code to handle this is a little longer.&lt;/p&gt;

&lt;p&gt;The HTML layout in Figure 3 is nearly identical to the HTML layout on the login form except there’s some conditional logic to display the input box or the checkbox and message that identifies the current OpenId association.&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;using &lt;/span&gt;(Html.BeginForm(&lt;span style="color: blue"&gt;new &lt;/span&gt;{ Controller = &lt;span style="color: #a31515"&gt;&amp;quot;Account&amp;quot;&lt;/span&gt;, Action = &lt;span style="color: #a31515"&gt;&amp;quot;OpenIdRegistrationLogOn&amp;quot; &lt;/span&gt;})){ &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;         
         &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;fieldset &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;                             
         &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;containercontent&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;padding&lt;/span&gt;: &lt;span style="color: blue"&gt;10px 20px&lt;/span&gt;;&lt;span style="color: blue"&gt;&amp;quot; &amp;gt;
             
             
            &lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: blue"&gt;if&lt;/span&gt;( &lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(Model.busUser.Entity.OpenId) ) { &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;                 &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;label &lt;/span&gt;&lt;span style="color: red"&gt;for&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openid_identifier&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;labelheaderblock&amp;quot;&amp;gt;&lt;/span&gt;Enter an OpenId Url:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;label&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openid_identifier&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;size&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;40&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openid_identifier&amp;quot;/&amp;gt;             
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btnOpenIdLogin&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;submit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Login&amp;quot;/&amp;gt; 
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;imgOpenIdLoginProgress&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/css/images/loading_small.gif&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;display&lt;/span&gt;:&lt;span style="color: blue"&gt;none&amp;quot; /&amp;gt;                 
                 
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;divOpenIdIcons&amp;quot;&amp;gt;
                     &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/images/openid-icon.png&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openIdUrl('openid')&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myopenid.com&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hoverbutton&amp;quot; /&amp;gt;
                     &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/images/google-icon.png&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openIdUrl('google')&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Google&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hoverbutton&amp;quot;/&amp;gt;
                     &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/images/yahoo-icon.png&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openIdUrl('yahoo')&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Yahoo&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hoverbutton&amp;quot; /&amp;gt;
                 &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                             
             &lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="color: blue"&gt;else &lt;/span&gt;{ &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;    
                 &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;label &lt;/span&gt;&lt;span style="color: red"&gt;for&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;openid_identifier&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;labelheaderblock&amp;quot;&amp;gt;&lt;/span&gt;OpenId Association&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;label&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;= ResolveUrl(&amp;quot;~/css/images/greencheck.gif&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot; /&amp;gt; &lt;/span&gt;This user account is linked to &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;b&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.Encode(Model.busUser.Entity.OpenId) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;b&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;input &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btnOpenIdUnlink&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;btnOpenIdUnlink&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;submit&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Unlink&amp;quot; /&amp;gt;                     
             &lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="background: #ffee62"&gt;%&amp;gt;

&lt;/span&gt;            &lt;strong&gt; &lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.Hidden(&lt;span style="color: #a31515"&gt;&amp;quot;Id2&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.Model.busUser.Entity.Id) &lt;/strong&gt;&lt;span style="background: #ffee62"&gt;&lt;strong&gt;%&amp;gt;&lt;/strong&gt;
&lt;/span&gt;         &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
         &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;fieldset&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Notice that here we need to keep track of the active User if any. Since you can attach/detach from an existing profile we do have to know which user we’re dealing with. This sounds easy enough but remember that you can’t use plain POST data for this because the page goes off the OpenId provider and comes back with a GET that just holds the result values. This means to redisplay the page the entire page has to be re-rendered based on the model. To do this we’ll need to keep track of the user id for the request sequence.&lt;/p&gt;

&lt;p&gt;This base process is very&amp;#160; similar to the log in process and uses the same two stages of request sending and return. First capture the value from a hidden form variable and then store it in the Session object to pass between the two requests. Here’s what the open id attachment/detachment code looks like:&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;AcceptVerbs&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;HttpVerbs&lt;/span&gt;.Post | &lt;span style="color: #2b91af"&gt;HttpVerbs&lt;/span&gt;.Get), &lt;span style="color: #2b91af"&gt;ValidateInput&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;)]
 &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;OpenIdRegistrationLogOn(&lt;span style="color: #2b91af"&gt;FormCollection &lt;/span&gt;formVars)
 {
     &lt;span style="color: blue"&gt;return &lt;/span&gt;OpenIdRegistrationLogOn(&lt;span style="color: blue"&gt;null&lt;/span&gt;,&lt;span style="color: blue"&gt;true&lt;/span&gt;);
 }
 
 &lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ActionResult &lt;/span&gt;OpenIdRegistrationLogOn(&lt;span style="color: #2b91af"&gt;IAuthenticationResponse &lt;/span&gt;response, &lt;span style="color: blue"&gt;bool &lt;/span&gt;reserved )
 {
     &lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewData[&lt;span style="color: #a31515"&gt;&amp;quot;IsNew&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;br /&gt;&lt;strong&gt;     &lt;span style="color: blue"&gt;var &lt;/span&gt;openid = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OpenIdRelyingParty&lt;/span&gt;();
    
     &lt;span style="color: blue"&gt;if &lt;/span&gt;(response == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
         response = openid.GetResponse();
&lt;/strong&gt;     
     &lt;span style="color: blue"&gt;if &lt;/span&gt;(response == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
     {
&lt;strong&gt;         &lt;span style="color: blue"&gt;string &lt;/span&gt;userId = Request.Form[&lt;span style="color: #a31515"&gt;&amp;quot;Id2&amp;quot;&lt;/span&gt;];  // have to track the user’s id
&lt;/strong&gt;
         &lt;span style="color: green"&gt;// Check for unlink operation
         &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(Request.Form[&lt;span style="color: #a31515"&gt;&amp;quot;btnOpenIdUnlink&amp;quot;&lt;/span&gt;]))
         {
             &lt;span style="color: blue"&gt;if &lt;/span&gt;(busUser.Load(userId) == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
             {
                 &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(&lt;span style="color: #a31515"&gt;&amp;quot;Couldn't find associated User: &amp;quot; &lt;/span&gt;+ busUser.ErrorMessage);
                 &lt;span style="color: blue"&gt;return &lt;/span&gt;RedirectToAction(&lt;span style="color: #a31515"&gt;&amp;quot;Register&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;{ id=userId });
             }
             busUser.Entity.OpenId = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
             busUser.Save();
             &lt;span style="color: blue"&gt;return &lt;/span&gt;RedirectToAction(&lt;span style="color: #a31515"&gt;&amp;quot;Register&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;{ id = userId });
         }

         &lt;span style="color: #2b91af"&gt;Identifier &lt;/span&gt;id;
         &lt;span style="color: blue"&gt;string &lt;/span&gt;openIdIdentifier = Request.Form[&lt;span style="color: #a31515"&gt;&amp;quot;openid_identifier&amp;quot;&lt;/span&gt;];
         &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Identifier&lt;/span&gt;.TryParse(openIdIdentifier, &lt;span style="color: blue"&gt;out &lt;/span&gt;id))
         {
             &lt;span style="color: blue"&gt;try
             &lt;/span&gt;{&lt;br /&gt;&lt;font color="#008000"&gt;&lt;strong&gt;                 // We need to know which user we are working with &lt;br /&gt;                 // and so we pass the id thru session – (is there a better way?) 
&lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;                 &lt;strong&gt;Session[&lt;span style="color: #a31515"&gt;&amp;quot;userId&amp;quot;&lt;/span&gt;] = userId;&lt;br /&gt;&lt;/strong&gt;
                 &lt;strong&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;req = openid.CreateRequest(id);
                 
                 &lt;span style="color: blue"&gt;var &lt;/span&gt;fields = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ClaimsRequest&lt;/span&gt;();                       
                 fields.Email = &lt;span style="color: #2b91af"&gt;DemandLevel&lt;/span&gt;.Request;
                 fields.FullName = &lt;span style="color: #2b91af"&gt;DemandLevel&lt;/span&gt;.Request;                        
                 req.AddExtension(fields);

                 &lt;span style="color: blue"&gt;return &lt;/span&gt;req.RedirectingResponse.AsActionResult();
             }&lt;/strong&gt;
             &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ProtocolException &lt;/span&gt;ex)
             {
                 &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(&lt;span style="color: #a31515"&gt;&amp;quot;Unable to authenticate: &amp;quot; &lt;/span&gt;+ ex.Message);
                 &lt;span style="color: blue"&gt;this&lt;/span&gt;.busUser.NewEntity();
                 &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;Register&amp;quot;&lt;/span&gt;,&lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
             }
         }
         &lt;span style="color: blue"&gt;else
         &lt;/span&gt;{
             ViewData[&lt;span style="color: #a31515"&gt;&amp;quot;Message&amp;quot;&lt;/span&gt;] = &lt;span style="color: #a31515"&gt;&amp;quot;Invalid identifier&amp;quot;&lt;/span&gt;;
             &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;Login&amp;quot;&lt;/span&gt;);
         }
     }
     &lt;span style="color: blue"&gt;else
     &lt;/span&gt;{&lt;br /&gt;&lt;strong&gt;&lt;font color="#008000"&gt;         // Reestablish the user we’re dealing with&lt;/font&gt;&lt;/strong&gt;
&lt;strong&gt;&lt;br /&gt;         &lt;span style="color: blue"&gt;string &lt;/span&gt;userId = Session[&lt;span style="color: #a31515"&gt;&amp;quot;userId&amp;quot;&lt;/span&gt;] &lt;span style="color: blue"&gt;as string&lt;/span&gt;;
         &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(userId))
             ViewData[&lt;span style="color: #a31515"&gt;&amp;quot;IsNew&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
         &lt;/strong&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;else
             &lt;/span&gt;ViewData[&lt;span style="color: #a31515"&gt;&amp;quot;IsNew&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;/strong&gt;

         &lt;span style="color: green"&gt;// Stage 3: OpenID Provider sending assertion response
         &lt;/span&gt;&lt;span style="color: blue"&gt;switch &lt;/span&gt;(response.Status)
         {
             &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AuthenticationStatus&lt;/span&gt;.Authenticated:
               &lt;strong&gt;  &lt;span style="color: blue"&gt;var &lt;/span&gt;claim = response.GetExtension&amp;lt;&lt;span style="color: #2b91af"&gt;ClaimsResponse&lt;/span&gt;&amp;gt;();
                 &lt;span style="color: blue"&gt;string &lt;/span&gt;email = &lt;span style="color: blue"&gt;null&lt;/span&gt;, fullname= &lt;span style="color: blue"&gt;null&lt;/span&gt;;
                 &lt;span style="color: blue"&gt;if &lt;/span&gt;(claim != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                 {
                     email = claim.Email;
                     fullname = claim.FullName;
                 }
                 &lt;span style="color: blue"&gt;string &lt;/span&gt;identifier = response.ClaimedIdentifier;&lt;/strong&gt;

                 &lt;strong&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;user = busUser.Load(userId);&lt;/strong&gt;
                 &lt;span style="color: blue"&gt;if &lt;/span&gt;(user == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                 {
                     &lt;strong&gt;user = busUser.ValidateUserOpenIdAndLoad(identifier);&lt;/strong&gt;
                     &lt;span style="color: blue"&gt;if &lt;/span&gt;(user == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                         user = busUser.NewEntity();
                 }
                 
                 &lt;span style="color: green"&gt;// associate openid with the user account
                 &lt;/span&gt;&lt;strong&gt;busUser.Entity.OpenId = identifier;&lt;/strong&gt;

                 &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(email) &amp;amp;&amp;amp; &lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(busUser.Entity.Email))
                     busUser.Entity.Email = email;

                 &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(fullname) &amp;amp;&amp;amp; &lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(busUser.Entity.Name))
                     busUser.Entity.Name = fullname;

                 &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(busUser.Entity.Name))
                 {
                     &lt;span style="color: blue"&gt;string &lt;/span&gt;host = &lt;span style="color: #2b91af"&gt;StringUtils&lt;/span&gt;.ExtractString(response.FriendlyIdentifierForDisplay, &lt;span style="color: #a31515"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;.com&amp;quot;&lt;/span&gt;);
                     &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(host))
                         host = &lt;span style="color: #a31515"&gt;&amp;quot; (&amp;quot; &lt;/span&gt;+ host + &lt;span style="color: #a31515"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;;
                    
                     busUser.Entity.Name = &lt;span style="color: #a31515"&gt;&amp;quot;Unknown&amp;quot; &lt;/span&gt;+ host;

                     &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.DisplayErrors.Add(&lt;span style="color: #a31515"&gt;&amp;quot;Please enter a user name&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;);
                 }

                 &lt;span style="color: blue"&gt;if &lt;/span&gt;(!busUser.Validate())
                 {
                     busUser.Entity.OpenId = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
                     &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(busUser.ErrorMessage);
                     &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;Register&amp;quot;&lt;/span&gt;,&lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
                 }
               &lt;strong&gt;  &lt;span style="color: blue"&gt;if &lt;/span&gt;(!busUser.Save())&lt;/strong&gt;
                 {
                     busUser.Entity.OpenId = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
                     &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(busUser.ErrorMessage);
                     &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;Register&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
                 }

                &lt;strong&gt; &lt;span style="color: #2b91af"&gt;UserState &lt;/span&gt;userState = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UserState&lt;/span&gt;()
                 {
                     Name = busUser.Entity.Name,
                     Email = busUser.Entity.Name,
                     UserId = busUser.Entity.Id,
                     IsAdmin = busUser.Entity.IsAdmin
                 };
                 &lt;span style="color: blue"&gt;this&lt;/span&gt;.IssueAuthTicket(userState, &lt;span style="color: blue"&gt;true&lt;/span&gt;);

                 &lt;/strong&gt;&lt;strong&gt;&lt;span style="color: green"&gt;// and reload the page with the saved data
                 &lt;/span&gt;&lt;span style="color: blue"&gt;return this&lt;/span&gt;.RedirectToAction(&lt;span style="color: #a31515"&gt;&amp;quot;Register&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;{ id=busUser.Entity.Id } );&lt;/strong&gt;
             &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AuthenticationStatus&lt;/span&gt;.Canceled:
                 &lt;span style="color: blue"&gt;this&lt;/span&gt;.busUser.NewEntity(&lt;span style="color: blue"&gt;true&lt;/span&gt;);
                 &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowMessage(&lt;span style="color: #a31515"&gt;&amp;quot;Canceled at provider&amp;quot;&lt;/span&gt;);
                 &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;Register&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
             &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #2b91af"&gt;AuthenticationStatus&lt;/span&gt;.Failed:
                 &lt;span style="color: blue"&gt;this&lt;/span&gt;.busUser.NewEntity(&lt;span style="color: blue"&gt;true&lt;/span&gt;);
                 &lt;span style="color: blue"&gt;this&lt;/span&gt;.ErrorDisplay.ShowError(response.Exception.Message);
                 &lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;Register&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;this&lt;/span&gt;.ViewModel);
         }
     }
     &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EmptyResult&lt;/span&gt;();
 }&lt;/pre&gt;


&lt;pre class="code"&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;There are two methods here – one as an actual endpoint and another that can be called with an existing response passed to it – this is useful to automatically force a login that doesn’t exist directly into the registration form via code. A DotNetAuth response can only be parsed once or else it’s considered invalid and so passing in an existing response was a requirement to handle this sort of ‘manual’ routing.&amp;#160; For the simple callback scenario you can just use a simple Controller endpoint method.&lt;/p&gt;

&lt;p&gt;As in the last example the OpenIdRelyingParty is used to handle the actual request semantics of sending the redirect and receiving the data. This part of the process really doesn’t change. However, how you deal with the data received and abort scenarios adds a significant amount of additional code compared to the previous login only example.&lt;/p&gt;

&lt;p&gt;If there’s no OpenId response, the code first checks for unlink requests. For this it needs the id to load an instance of the business entity and update it by removing the OpenId from it. The page is then redisplayed again using the ID as the key. &lt;/p&gt;

&lt;p&gt;Otherwise the request is sent off to the OpenId provider. The provider then returns and again the OpenId response will now be set. On success the code tries to retrieve the ClaimsRequest values. Claimsrequest is sent with the initial request to ask the server to return values from the user’s profile. For CodePaste.net I’m interested in full name and email as optional results. Note that some OpenId only providers use a common format called SREG to return values. myOpenDns does as do several other of the dedicated services. However, this standards is only sketchily supported by the big providers. Google for example requires that you Demand data and then will only return the email address (which seems ironic given that’s the most private item in the profile). Yahoo doesn’t return anything – according to their OpenId page they only share profile information with certain sites they deem appropriate. SREG however is gaining momentum so it’s likely that all providers will evenutally support SREG.&lt;/p&gt;

&lt;p&gt;In DotnetOpenAuth the request for ‘claim data’ is handled like this:&lt;/p&gt;
&lt;font color="#008000" face="Courier New"&gt;// Request additional Profile 
  &lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;req = openid.CreateRequest(Request.Form[&lt;span style="color: #a31515"&gt;&amp;quot;openid_identifier&amp;quot;&lt;/span&gt;]); &lt;font color="#008000"&gt;information with ClaimsRequest&lt;/font&gt; 

    &lt;br /&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;fields = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ClaimsRequest&lt;/span&gt;(); 

    &lt;br /&gt;fields.Email = &lt;span style="color: #2b91af"&gt;DemandLevel&lt;/span&gt;.Demand; 

    &lt;br /&gt;fields.FullName = &lt;span style="color: #2b91af"&gt;DemandLevel&lt;/span&gt;.Demand; 

    &lt;br /&gt;req.AddExtension(fields); &lt;/font&gt;&lt;/font&gt;

&lt;p&gt;You can Request or Demand claims. In theory Demand means that if the provider or user refuses to provide the requested keys the request fails. In reality though providers like google ignore Request commands and so Demand is often required to retrieve information.&lt;/p&gt;

&lt;p&gt;To retrieve the claims data uses GetExtension&amp;lt;T&amp;gt;():&lt;/p&gt;
&lt;font color="#008000" size="2" face="Courier New"&gt;// Retrieve custom profile information if available 
  &lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;claim = response.GetExtension&amp;lt;&lt;span style="color: #2b91af"&gt;ClaimsResponse&lt;/span&gt;&amp;gt;(); 

    &lt;br /&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;email = &lt;span style="color: blue"&gt;null&lt;/span&gt;, fullname= &lt;span style="color: blue"&gt;null&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;/span&gt; 

    &lt;br /&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(claim != &lt;span style="color: blue"&gt;null&lt;/span&gt;) 

    &lt;br /&gt;{ 

    &lt;br /&gt;&amp;#160; email = claim.Email; 

    &lt;br /&gt;&amp;#160; fullname = claim.FullName; 

    &lt;br /&gt;} &lt;/font&gt;&lt;/font&gt;

&lt;p&gt;Just remember that there’s no guarantee these values are set.&lt;/p&gt;

&lt;p&gt;The other issue in this controller deals with state management of the user. When the user comes to the page to hook up we have state on the page for that particular user, but when we re-direct to the OpenId provider site we loose that state. So in this case the user id needs to be tracked and I’m using a Session object for this.&amp;#160; I haven’t had much need for session in MVC applications but this is one case where I don’t see a way around this unfortunately. Before the request is sent the user’s id is stored in a Session object. When the authenticated request returns the session id is retrieved and used to look up the user’s business object which is the updated with the open id identifier and optionally the profile information if any. The rest of the bulky code deals with a few checks on the data returned and isolating which data to update.&lt;/p&gt;

&lt;h3&gt;OpenId Integration – More complicated than it looks&lt;/h3&gt;

&lt;p&gt;Phew – this looks like a lot of code you have to write and while it’s a pretty good chunk the largest part of this code has to do with the business logic to save and update the user’s information and setting the Forms Authentication ticket. The actual OpenId related logic is relatively simple once you understand the basic concept of how the flow of an OpenId authentication works.&lt;/p&gt;

&lt;p&gt;As any Web based callback mechanism the code is bulky because you have to effectively route the responses inside your code and you end up with some code that couples Web and business logic which is always ugly. I remember fighting similar issues years ago with PayPal integration.&amp;#160; Processes like these are cumbersome because they are so closely tied to the actual Web request – the Controller Action in this case and don’t provide for an easy way to abstract and wrap into business logic. That’s the penalty you pay for a distributed system in many situations and this is no different.&lt;/p&gt;

&lt;p&gt;There are also other solution out there for OpenId integration. &lt;a href="http://blog.wekeroad.com/"&gt;Rob Conery&lt;/a&gt; has been mucking around and trying to convince me to try &lt;a href="https://rpxnow.com/"&gt;RPX&lt;/a&gt; which uses a man in the middle approach for hosting OpenId authentication. They basically provide the login API via a pop up window and you then retrieve the authentication data via a backend service call. But this requires yet another provider in the middle that you talk to through a proprietary API. It might help isolating the auth logic (service callback vs. a controller action). But it’s not for me – but for some of you this might be interesting to check out especially if you like the way the RPX looks. It'll definitely be a less code approach.&lt;/p&gt;

&lt;p&gt;I hope though that this article is useful to some of you. I certainly wish I would have had something to look at when I started looking at OpenId.There’s a lot of high level posturing stuff out there that talks about the benefits and goals of open ID but preciously little code that actually shows the progression of steps in context that explains OpenId flow on a high level along with an implementation. &lt;/p&gt;

&lt;p&gt;I also want to thank &lt;/p&gt;

&lt;h3&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://dotnetopenauth.net:8000/"&gt;&lt;strong&gt;DotNetOpenAuth Library&lt;/strong&gt;&lt;/a&gt; 

    &lt;br /&gt;.NET library for processing OpenId, oAuth, InfoCard and various other authentication APIs. Very comprehensive and thoughtful functionality although documentation is a bit on the sparse side. Excellent support and feedback from the developer who’s really passionate about this library and closely monitors and listens to feedback. 

    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://codepaste.net/docs?page=_2pz00b3po.htm"&gt;&lt;strong&gt;CodePaste.net Source Code&lt;/strong&gt;&lt;/a&gt; 

    &lt;br /&gt;This article is based on the code on CodePaste.net and if you like you can check out the source code from the Subversion repository. &lt;/li&gt;
&lt;/ul&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category= ASP.NET'&gt; ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=MVC'&gt;MVC&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f899303.aspx&amp;title=Integrating+OpenID+in+an+ASP.NET+MVC+Application+using+DotNetOpenAuth"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f899303.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=iWRtB-LxKJ8:JrAwvEk-gek:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=iWRtB-LxKJ8:JrAwvEk-gek:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=iWRtB-LxKJ8:JrAwvEk-gek:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=iWRtB-LxKJ8:JrAwvEk-gek:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=iWRtB-LxKJ8:JrAwvEk-gek:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=iWRtB-LxKJ8:JrAwvEk-gek:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=iWRtB-LxKJ8:JrAwvEk-gek:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=iWRtB-LxKJ8:JrAwvEk-gek:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=iWRtB-LxKJ8:JrAwvEk-gek:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/iWRtB-LxKJ8" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/899303.aspx</feedburner:origLink></item>
    <item>
      <title>Making  jQuery calls to WCF/ASMX with a ServiceProxy Client</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/Zozu7rDvFAg/896411.aspx</link>
      <guid isPermaLink="false">896411_200909160331</guid>
      <pubDate>Wed, 16 Sep 2009 03:31:07 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/896411.aspx#Comments</comments>
      <slash:comments>11</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=896411</wfw:commentRss>
      <category> ASP.NET</category>
      <category>jQuery</category>
      <category>JavaScript</category>
      <description>&lt;p&gt;I’ve discussed creating a WCF or ASMX Service proxy for operation with jQuery and without using the Microsoft AJAX libraries. This was some time ago and some things have changed since then – most notably the introduction &lt;a href="http://www.west-wind.com/weblog/posts/729630.aspx"&gt;native JSON parsers in IE 8 and FireFox 3.5&lt;/a&gt; as well as some changes in .NET 3.5 SP1 that makes some JSON transfer tasks a little bit easier in some situations. So I think it’s time to revisit this topic and update the code I showed in the past.&lt;/p&gt;  &lt;h3&gt;How the WCF ServiceProxy works&lt;/h3&gt;  &lt;p&gt;The idea of the service proxy is to make it as easy as a single function call to call a WCF or ASMX service. There no dependencies here other than jQuery.js. The goal is to initialize the proxy with a URL and then simply call .invoke() methods to call service methods on the service. The resulting client code using the proxy looks like the following.&lt;/p&gt;  &lt;p&gt;Include a script reference into the page in the header:&lt;/p&gt;  &lt;pre class="code"&gt; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;../scripts/serviceproxy.js&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;     
&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;There are two steps to calling services: Initializing the proxy which can be done globally at the top of the script code and then actually making the service method callbacks.&lt;/p&gt;

&lt;p&gt;Start by adding the initialization code in a global location on your page or in a separate external .js file:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// *** Create a static service instance (serviceProxy.js)
// *** which includes ServiceProxy, JSON2, and JSON extensions 
&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;serviceUrl = &lt;span style="color: #a31515"&gt;&amp;quot;BasicWcfService.svc/&amp;quot;&lt;/span&gt;;
&lt;span style="color: blue"&gt;var &lt;/span&gt;proxy = &lt;span style="color: blue"&gt;new &lt;/span&gt;ServiceProxy(serviceUrl);&lt;/pre&gt;


&lt;p&gt;Then you’re ready to make service calls. The following is the ever illustrious HelloWorld request called from a click button handler:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;showHelloWorld()
{
    proxy.invoke(&lt;span style="color: #a31515"&gt;&amp;quot;HelloWorld&amp;quot;&lt;/span&gt;,
         { name: $(&lt;span style="color: #a31515"&gt;&amp;quot;#&amp;quot; &lt;/span&gt;+ serverVars.txtHelloNameId).val() },
         &lt;span style="color: blue"&gt;function&lt;/span&gt;(result) {
             $(&lt;span style="color: #a31515"&gt;&amp;quot;#divHelloWorldResult&amp;quot;&lt;/span&gt;)
                .text(result)
                .slideUp(&lt;span style="color: #a31515"&gt;&amp;quot;hide&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function&lt;/span&gt;() { $(&lt;span style="color: blue"&gt;this&lt;/span&gt;).slideDown(&lt;span style="color: #a31515"&gt;&amp;quot;slow&amp;quot;&lt;/span&gt;) });
         },
         onPageError, &lt;span style="color: blue"&gt;false&lt;/span&gt;);
}&lt;/pre&gt;


&lt;p&gt;The individual .invoke calls then simply specify the method to call on the server, and an object map with parameter names as properties. So the HelloWorld method has a &lt;em&gt;name&lt;/em&gt; parameter hence { name: &amp;quot;Rick&amp;quot; } is sent. If you had multiple parameters the map would have multiple properties: { parm1: &amp;quot;rick&amp;quot;, parm2: 10, parm3: new Date() }. Parameter types can be of any type as long as they match in structure what the server’s method expects.&lt;/p&gt;

&lt;p&gt;The third and fourth parameters are the success callback which receives the result value, and the failure callback which receives an exception like object. The success handler typically is used to assign the result value to the page somehow by displaying some notification or message, or updating some page content. Here an anonymous function is used inline to handle the success callback which receives the result of the service callback – in this case a string of an HTML fragment – as a parameter. The html is then promptly embedded into the page and made visible with a small effect.&lt;/p&gt;

&lt;h3&gt;Setting up a WCF Service on the Server&lt;/h3&gt;

&lt;p&gt;On the server side a WCF Service that implements the service methods using the WCF AJAX style WebScriptServiceHostFactory can be set up like this: 
  &lt;br /&gt;

  &lt;br /&gt;Go into web.config file and REMOVE all the System.ServiceModel entries created from the WCF service 

  &lt;br /&gt;Open the .SVC file created and add the Factory attribute to the page as shown below 

  &lt;br /&gt;

  &lt;br /&gt;&lt;font face="Courier New"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@&lt;/span&gt;&lt;span style="color: #a31515"&gt;ServiceHost &lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;=&amp;quot;C#&amp;quot; 
      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: red"&gt;Service&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;=&amp;quot;WcfAjax.BasicWcfService&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: red"&gt;CodeBehind&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: blue"&gt;=&amp;quot;BasicWcfService.cs&amp;quot; 
      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: red"&gt;Factory&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;System.ServiceModel.Activation.WebScriptServiceHostFactory&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;span style="background: #ffee62"&gt;&lt;font face="Courier New"&gt;%&amp;gt; 
      &lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;


&lt;p&gt;Notice the &lt;span style="color: red"&gt;Factory&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;System.ServiceModel.Activation.WebScriptServiceHostFactory&amp;quot; &lt;/span&gt;definition in the markup page – this is a shortcut for Microsoft AJAX style messaging that allows you to bypass all web.config configuration. In fact you can remove all WCF related entries from the config file if you like once you use the script factory. You can still use the web.config settings – they will override the defaults, but typically that is not required. If you want ASP.NET compatibility you might want to add one thing to the .config file:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;serviceHostingEnvironment &lt;/span&gt;&lt;span style="color: red"&gt;aspNetCompatibilityEnabled&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;true&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;All that’s left to do then is to set up the service and service methods. For simplicity I’m just using a class that implements the contract. If you want to be anal and prefer setting up a separate ServiceContract interface for an internal service class that will never be reused be my guest – but for most application internal AJAX services that hardly a necessary practice.&lt;/p&gt;

&lt;p&gt;Here’s is the service class:&lt;/p&gt;

&lt;pre class="code"&gt;    [&lt;span style="color: #2b91af"&gt;ServiceContract&lt;/span&gt;(Namespace = &lt;span style="color: #a31515"&gt;&amp;quot;DevConnections&amp;quot;&lt;/span&gt;)]
    [&lt;span style="color: #2b91af"&gt;AspNetCompatibilityRequirements&lt;/span&gt;(RequirementsMode = &lt;span style="color: #2b91af"&gt;AspNetCompatibilityRequirementsMode&lt;/span&gt;.Required)]
&lt;span style="color: blue"&gt;#if &lt;/span&gt;DEBUG 
    &lt;span style="color: gray"&gt;[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
&lt;/span&gt;&lt;span style="color: blue"&gt;#endif
    public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;BasicWcfService
    &lt;/span&gt;{
        [&lt;span style="color: #2b91af"&gt;OperationContract&lt;/span&gt;]&lt;span style="color: green"&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public string &lt;/span&gt;HelloWorld(&lt;span style="color: blue"&gt;string &lt;/span&gt;name)
        {
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Hello &amp;quot; &lt;/span&gt;+ name +&lt;span style="color: #a31515"&gt;&amp;quot;. Time is: &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;.Now.ToString();
        }

        [&lt;span style="color: #2b91af"&gt;OperationContract&lt;/span&gt;]&lt;span style="color: green"&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StockQuote &lt;/span&gt;GetStockQuote(&lt;span style="color: blue"&gt;string &lt;/span&gt;symbol)
        {
            &lt;span style="color: #2b91af"&gt;StockServer &lt;/span&gt;server = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StockServer&lt;/span&gt;();
            &lt;span style="color: #2b91af"&gt;StockQuote &lt;/span&gt;quote;

            &lt;span style="color: blue"&gt;return &lt;/span&gt;server.GetStockQuote(symbol);
        }

        [&lt;span style="color: #2b91af"&gt;OperationContract&lt;/span&gt;]&lt;span style="color: green"&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StockQuote&lt;/span&gt;[] GetStockQuotes(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] symbols)
        {
            &lt;span style="color: #2b91af"&gt;StockServer &lt;/span&gt;server = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StockServer&lt;/span&gt;();      
            &lt;span style="color: blue"&gt;return &lt;/span&gt;server.GetStockQuotes(symbols);
        }

        [&lt;span style="color: #2b91af"&gt;OperationContract&lt;/span&gt;] 
        [&lt;span style="color: #2b91af"&gt;WebGet&lt;/span&gt;]
        &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Stream &lt;/span&gt;GetStockHistoryGraph(&lt;span style="color: blue"&gt;string &lt;/span&gt;stockSymbols,&lt;span style="color: blue"&gt;string &lt;/span&gt;title, &lt;span style="color: blue"&gt;int &lt;/span&gt;width, &lt;span style="color: blue"&gt;int &lt;/span&gt;height)
        {
            &lt;span style="color: blue"&gt;string&lt;/span&gt;[] symbols = stockSymbols.Split(&lt;span style="color: #a31515"&gt;','&lt;/span&gt;);
            
            &lt;span style="color: #2b91af"&gt;StockServer &lt;/span&gt;server = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StockServer&lt;/span&gt;();
            &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] img = server.GetStockHistoryGraph(symbols, title, width, height, 2);

            &lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;ms = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;(img);
            &lt;span style="color: blue"&gt;return &lt;/span&gt;ms;
        }

        [&lt;span style="color: #2b91af"&gt;OperationContract&lt;/span&gt;]&lt;span style="color: green"&gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;AddDays(&lt;span style="color: #2b91af"&gt;DateTime &lt;/span&gt;date, &lt;span style="color: blue"&gt;int &lt;/span&gt;days)
        {
            &lt;span style="color: blue"&gt;return &lt;/span&gt;date.AddDays(days); 
        }

        [&lt;span style="color: #2b91af"&gt;OperationContract&lt;/span&gt;]
&lt;span style="color: green"&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;public string &lt;/span&gt;ThrowServerException()
        {
            &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;User generated Error. This error has been purposefully created on the server&amp;quot;&lt;/span&gt;);
            &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Gotcha!&amp;quot;&lt;/span&gt;;
        }
    }&lt;/pre&gt;

&lt;p&gt;Nothing fancy here – just methods marked up with [OperationContract] attributes and a service class that implements the [ServiceContract] and you’re ready to go.&lt;/p&gt;

&lt;h3&gt;Calling the Service – Another example&lt;/h3&gt;

&lt;p&gt;For a slightly more involved example let’s call the GetStockQuotes method on the server which returns a result that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="StockList[4]" border="0" alt="StockList[4]" src="http://www.west-wind.com/Weblog/images/200901/WindowsLiveWriter/AnUpdateforajQueryWCFClientServiceProxy_ECB6/StockList%5B4%5D_4923fac3-c8dd-4df9-b24e-5086519f90e0.png" width="701" height="369" /&gt; &lt;/p&gt;

&lt;p&gt;The result here is returned as an array of objects that contains stock quotes, which is then rendered into the page on the client via a ‘filling the holes’ template approach (there are other ways to &lt;a href="http://www.west-wind.com/Weblog/posts/509108.aspx"&gt;accomplish this using templates&lt;/a&gt;). Here’s what this request looks like:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;getStockQuotes() {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;symbols = $(&lt;span style="color: #a31515"&gt;&amp;quot;#&amp;quot; &lt;/span&gt;+ serverVars.txtSymbolsId ).val().split(&lt;span style="color: #a31515"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;);
    proxy.invoke(&lt;span style="color: #a31515"&gt;&amp;quot;GetStockQuotes&amp;quot;&lt;/span&gt;,
         { symbols: symbols },  &lt;span style="color: green"&gt;// pass symbol array as 'symbols' parameter
         &lt;/span&gt;&lt;span style="color: blue"&gt;function&lt;/span&gt;(quotes) {  &lt;span style="color: green"&gt;// result is an array for each of the symbols                            
             &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;jCnt = $(&lt;span style="color: #a31515"&gt;&amp;quot;#divStockDisplay&amp;quot;&lt;/span&gt;).fadeIn(&lt;span style="color: #a31515"&gt;&amp;quot;slow&amp;quot;&lt;/span&gt;);
             &lt;span style="color: blue"&gt;var &lt;/span&gt;jDiv = $(&lt;span style="color: #a31515"&gt;&amp;quot;#divStockContent&amp;quot;&lt;/span&gt;).empty();

             &lt;span style="color: green"&gt;// quotes is an array
             &lt;/span&gt;$.each(quotes, &lt;span style="color: blue"&gt;function&lt;/span&gt;(index) {
                 &lt;span style="color: blue"&gt;var &lt;/span&gt;jCtl = $(&lt;span style="color: #a31515"&gt;&amp;quot;#StockItemTemplate&amp;quot;&lt;/span&gt;).clone();
                 jCtl.attr(&lt;span style="color: #a31515"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;stock_&amp;quot; &lt;/span&gt;+ &lt;span style="color: blue"&gt;this&lt;/span&gt;.Symbol);
                 &lt;span style="color: blue"&gt;var &lt;/span&gt;symbol = &lt;span style="color: blue"&gt;this&lt;/span&gt;.Symbol;

                 jCtl.find(&lt;span style="color: #a31515"&gt;&amp;quot;.itemstockname&amp;quot;&lt;/span&gt;).text(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Company);
                 jCtl.find(&lt;span style="color: #a31515"&gt;&amp;quot;#tdLastPrice&amp;quot;&lt;/span&gt;).text(&lt;span style="color: blue"&gt;this&lt;/span&gt;.LastPrice.formatNumber(&lt;span style="color: #a31515"&gt;&amp;quot;n2&amp;quot;&lt;/span&gt;));
                 jCtl.find(&lt;span style="color: #a31515"&gt;&amp;quot;#tdOpenPrice&amp;quot;&lt;/span&gt;).text(&lt;span style="color: blue"&gt;this&lt;/span&gt;.OpenPrice.formatNumber(&lt;span style="color: #a31515"&gt;&amp;quot;n2&amp;quot;&lt;/span&gt;));
                 jCtl.find(&lt;span style="color: #a31515"&gt;&amp;quot;#tdNetChange&amp;quot;&lt;/span&gt;).text(&lt;span style="color: blue"&gt;this&lt;/span&gt;.NetChange.formatNumber(&lt;span style="color: #a31515"&gt;&amp;quot;n2&amp;quot;&lt;/span&gt;));
                 jCtl.find(&lt;span style="color: #a31515"&gt;&amp;quot;#tdTradeDate&amp;quot;&lt;/span&gt;).text(&lt;span style="color: blue"&gt;this&lt;/span&gt;.LastQuoteTimeString);
                 jCtl.fadeIn().click(&lt;span style="color: blue"&gt;function&lt;/span&gt;() { alert(&lt;span style="color: #a31515"&gt;'clicked on: ' &lt;/span&gt;+ symbol); });
                 jCtl.find(&lt;span style="color: #a31515"&gt;&amp;quot;.hoverbutton&amp;quot;&lt;/span&gt;).click(&lt;span style="color: blue"&gt;function&lt;/span&gt;(e) { alert(&lt;span style="color: #a31515"&gt;&amp;quot;delete clicked on: &amp;quot; &lt;/span&gt;+ symbol); e.stopPropagation(); });

                 jDiv.append(jCtl);
             });
         },
         onPageError);                          
}&lt;/pre&gt;


&lt;p&gt;The code takes an input string of comma delimited symbols, splits them into an array symbols. The symbols array is attached to the parameter map in the call to .invoke() as the input parameter to GetStockQuotes of the service method. The callback handler receives the array of quotes and creates a new list of stock item templates. The ‘template’ is really just an invisible HTML fragment:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;&amp;lt;!-- 'Template' used to render each of the stock items --&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;StockItemTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemtemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;style&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;display&lt;/span&gt;:&lt;span style="color: blue"&gt;none&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;stockicon&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemtools&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;='javascript:{}' &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;hoverbutton&amp;quot; &amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;img &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;../images/remove.gif&amp;quot; /&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemstockname&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;itemdetail&amp;quot;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;table &lt;/span&gt;&lt;span style="color: red"&gt;cellpadding&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Price:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tdLastPrice&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;stockvaluecolumn&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Open:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tdOpenPrice&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;stockvaluecolumn&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Change:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tdNetChange&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;stockvaluecolumn&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;                
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;td &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tdTradeDate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;colspan&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;td&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;tr&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;table&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;and the code reads this fragment, clones it and then fills in the ‘holes’ with the retrieved data. Each individual StockItem is then added to the the list container (divStockContent) to display the list.&lt;/p&gt;

&lt;p&gt;The data for all of this is using JSON and the stock array that is returned from the server looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;{&lt;span style="color: #a31515"&gt;&amp;quot;d&amp;quot;&lt;/span&gt;:[{&lt;span style="color: #a31515"&gt;&amp;quot;__type&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;StockQuote:#StockPortfolio&amp;quot;&lt;/span&gt;,
       &lt;span style="color: #a31515"&gt;&amp;quot;Company&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;Microsoft Corpora&amp;quot;&lt;/span&gt;,
       &lt;span style="color: #a31515"&gt;&amp;quot;LastPrice&amp;quot;&lt;/span&gt;:25.20,
       &lt;span style="color: #a31515"&gt;&amp;quot;LastQuoteTime&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;\/Date(1253055600000-0700)\/&amp;quot;&lt;/span&gt;,
       &lt;span style="color: #a31515"&gt;&amp;quot;LastQuoteTimeString&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;Sep 15, 4:00PM&amp;quot;&lt;/span&gt;,
       &lt;span style="color: #a31515"&gt;&amp;quot;NetChange&amp;quot;&lt;/span&gt;:0.20,
       &lt;span style="color: #a31515"&gt;&amp;quot;OpenPrice&amp;quot;&lt;/span&gt;:24.95,
       &lt;span style="color: #a31515"&gt;&amp;quot;Symbol&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;MSFT&amp;quot;&lt;/span&gt;},
      {&lt;span style="color: #a31515"&gt;&amp;quot;__type&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;StockQuote:#StockPortfolio&amp;quot;&lt;/span&gt;,
       &lt;span style="color: #a31515"&gt;&amp;quot;Company&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;Intel Corporation&amp;quot;&lt;/span&gt;,
       &lt;span style="color: #a31515"&gt;&amp;quot;LastPrice&amp;quot;&lt;/span&gt;:19.55,
       &lt;span style="color: #a31515"&gt;&amp;quot;LastQuoteTime&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;\/Date(1253055600000-0700)\/&amp;quot;&lt;/span&gt;,
       &lt;span style="color: #a31515"&gt;&amp;quot;LastQuoteTimeString&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;Sep 15, 4:00PM&amp;quot;&lt;/span&gt;,
       &lt;span style="color: #a31515"&gt;&amp;quot;NetChange&amp;quot;&lt;/span&gt;:0.19,
       &lt;span style="color: #a31515"&gt;&amp;quot;OpenPrice&amp;quot;&lt;/span&gt;:19.51,
       &lt;span style="color: #a31515"&gt;&amp;quot;Symbol&amp;quot;&lt;/span&gt;:&lt;span style="color: #a31515"&gt;&amp;quot;INTC&amp;quot;&lt;/span&gt;}
    ]
 }&lt;/pre&gt;

&lt;p&gt;Notice that this is Microsoft’s funky encoding format that includes a ‘wrapping’ type &lt;em&gt;d&lt;/em&gt; that is consistent WCFs serialization formatting. The serviceProxy client however cleans this up. The data contains various types which are preserved on the client and also back up to the server if you post data back. And notice the funky date format which is also Microsoft specific (&amp;quot;\/Date(999123312)\/&amp;quot;). The serviceProxy properly deserializes these dates as well so result[0].LastQuoteTime will be a date. It also handles proper encoding of dates that are sent to the server so they appear as dates there.&lt;/p&gt;

&lt;p&gt;The sample is part of the jQuery samples linked at the bottom of this post if you want to check it out a little closer and play with it for yourself.&lt;/p&gt;

&lt;p&gt;Ok so much for the background…&lt;/p&gt;

&lt;h3&gt;ServiceProxy Implementation&lt;/h3&gt;

&lt;p&gt;I have previously written about the ServiceProxy implementation, but there have been a number of changes that had to be made to deal with recent changes in the browser world namely the addition of native JSON parsers. The old version I created relied on a customized version of &lt;a href="http://www.json.org/js.html"&gt;Douglas CrockFord’s JSON2.js file&lt;/a&gt;. It was customized to handle the date encoding and decoding. JSON2.js is still required since not all browsers support native JSON parsing (only IE 8 and FF 3.5 currently do), but it’s fully compatible to the native JSON parser’s object model so it’s a perfect fit.&lt;/p&gt;

&lt;p&gt;However with the advent of native JSON parsers the ‘customization’ of JSON2.js is no longer possible since the native implementations are fixed and immutable. They are also significantly faster so we definitely want to take advantage of this new feature. JSON parsers allow for a Replacer (stringify) and Reviver (parse) function that can be used to provide some post parsing formatting which allows hooking up the date processing both to the native parsers as well as the JSON2 parser with the same code.&lt;/p&gt;

&lt;p&gt;I’ve included a ServiceProxy.js class with this post which provides all 3 items in a single file:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ServiceProxy class &lt;/li&gt;

  &lt;li&gt;JSON2 &lt;/li&gt;

  &lt;li&gt;JSON2 Extensions &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JSON2 is included in this package to have everything wrapped up in a single file for easier portability.&amp;#160; Alternately you can also grab &lt;a href="http://www.west-wind.com:8080/svn/WestwindWebToolkit/trunk/Westwind.Web/Resources/ww.jquery.js"&gt;ww.jquery.js&lt;/a&gt; which also includes all three of these components plus a host of jQuery plug-ins for typical AJAX use.&lt;/p&gt;

&lt;h3&gt;ServiceProxy Class&lt;/h3&gt;

&lt;p&gt;Let’s quickly look at the first and last components starting with the ServiceProxy. The service proxy is meant to make the service call easy. It relies on jQuery’s .ajax() function to make the actual callback. The proxy provides a number of useful features: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Single Method Service Calls &lt;/li&gt;

  &lt;li&gt;JSON encoding/decoding &lt;/li&gt;

  &lt;li&gt;Consistent Error Handling &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The latter is an often overlooked part of using jQuery’s .ajax() function because it provides a&amp;#160; poor job of returning error information in a meaningful way. The proxy wraps errors into an object with a simple message regardless of whether you’re dealing with a transmission error, a client error or a service application fault.&lt;/p&gt;

&lt;p&gt;Here’s the ServiceProxy class implementation:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.ServiceProxy = &lt;span style="color: blue"&gt;function&lt;/span&gt;(serviceUrl) {
    &lt;span style="color: green"&gt;/// &amp;lt;summary&amp;gt;
    /// Generic Service Proxy class that can be used to
    /// call JSON Services generically using jQuery
    /// depends on JSON2.js modified for MS Ajax usage
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;serviceUrl&amp;quot; type=&amp;quot;string&amp;quot;&amp;gt;
    /// The Url of the service ready to accept the method name
    /// should contain trailing slash (or other URL separator ?,&amp;amp;)
    /// &amp;lt;/param&amp;gt;
    /// &amp;lt;example&amp;gt;
    /// var proxy = new ServiceProxy(&amp;quot;JsonStockService.svc/&amp;quot;);
    /// proxy.invoke(&amp;quot;GetStockQuote&amp;quot;,{symbol:&amp;quot;msft&amp;quot;},
    ///              function(quote) { alert(result.LastPrice); },onPageError);
    ///&amp;lt;/example&amp;gt;

    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;_I = &lt;span style="color: blue"&gt;this&lt;/span&gt;;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.serviceUrl = serviceUrl;
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.isWcf = &lt;span style="color: blue"&gt;true&lt;/span&gt;;

    &lt;span style="color: blue"&gt;this&lt;/span&gt;.invoke = &lt;span style="color: blue"&gt;function&lt;/span&gt;(method, params, callback, errorHandler, bare) {
        &lt;span style="color: green"&gt;/// &amp;lt;summary&amp;gt;
        /// Calls a WCF/ASMX service and returns the result.
        /// &amp;lt;/summary&amp;gt;    
        /// &amp;lt;param name=&amp;quot;method&amp;quot; type=&amp;quot;string&amp;quot;&amp;gt;The method of the service to call&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&amp;quot;params&amp;quot; type=&amp;quot;object&amp;quot;&amp;gt;An object that represents the parameters to pass {symbol:&amp;quot;msft&amp;quot;,years:2}       
        /// &amp;lt;param name=&amp;quot;callback&amp;quot; type=&amp;quot;function&amp;quot;&amp;gt;Function called on success. 
        /// Receives a single parameter of the parsed result value&amp;lt;/parm&amp;gt;
        /// &amp;lt;param name=&amp;quot;errorCallback&amp;quot; type=&amp;quot;function&amp;quot;&amp;gt;Function called on failure. 
        /// Receives a single error object with Message property&amp;lt;/parm&amp;gt;
        /// &amp;lt;param name=&amp;quot;isBare&amp;quot; type=&amp;quot;boolean&amp;quot;&amp;gt;Set to true if response is not a WCF/ASMX style 'wrapped' object&amp;lt;/parm&amp;gt;

        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;json = _I.isWcf ? JSON.stringifyWcf(params) : JSON.stringify(params);

        &lt;span style="color: green"&gt;// Service endpoint URL        
        &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;url = _I.serviceUrl + method;

        $.ajax({
            url: url,
            data: json,
            type: &lt;span style="color: #a31515"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;,
            processData: &lt;span style="color: blue"&gt;false&lt;/span&gt;,
            contentType: &lt;span style="color: #a31515"&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;,
            timeout: 10000,
            dataType: &lt;span style="color: #a31515"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;,  &lt;span style="color: green"&gt;// not &amp;quot;json&amp;quot; we'll parse
            &lt;/span&gt;success: &lt;span style="color: blue"&gt;function&lt;/span&gt;(res) {
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(!callback) &lt;span style="color: blue"&gt;return&lt;/span&gt;;

                &lt;span style="color: green"&gt;// Use json library so we can fix up MS AJAX dates
                &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;result = JSON.parseWithDate(res);

                &lt;span style="color: green"&gt;// Bare message IS result
                &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(bare)
                { callback(result); &lt;span style="color: blue"&gt;return&lt;/span&gt;; }

                &lt;span style="color: green"&gt;// Wrapped message contains top level object node
                // strip it off
                &lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;property &lt;span style="color: blue"&gt;in &lt;/span&gt;result) {
                    callback(result[property]);
                    &lt;span style="color: blue"&gt;break&lt;/span&gt;;
                }
            },
            error: &lt;span style="color: blue"&gt;function&lt;/span&gt;(xhr, status) {                
                &lt;span style="color: blue"&gt;var &lt;/span&gt;err = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(xhr.readyState == 4) {
                    &lt;span style="color: blue"&gt;var &lt;/span&gt;res = xhr.responseText;
                    &lt;span style="color: blue"&gt;if &lt;/span&gt;(res &amp;amp;&amp;amp; res.charAt(0) == &lt;span style="color: #a31515"&gt;'{'&lt;/span&gt;)
                        &lt;span style="color: blue"&gt;var &lt;/span&gt;err = JSON.parseWithDate(res);
                    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!err) {
                        &lt;span style="color: blue"&gt;if &lt;/span&gt;(xhr.status &amp;amp;&amp;amp; xhr.status != 200)
                            err = &lt;span style="color: blue"&gt;new &lt;/span&gt;CallbackException(xhr.status + &lt;span style="color: #a31515"&gt;&amp;quot; &amp;quot; &lt;/span&gt;+ xhr.statusText);
                        &lt;span style="color: blue"&gt;else
                            &lt;/span&gt;err = &lt;span style="color: blue"&gt;new &lt;/span&gt;CallbackException(&lt;span style="color: #a31515"&gt;&amp;quot;Callback Error: &amp;quot; &lt;/span&gt;+ status);
                        err.detail = res;
                    }
                }
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(!err)
                    err = &lt;span style="color: blue"&gt;new &lt;/span&gt;CallbackException(&lt;span style="color: #a31515"&gt;&amp;quot;Callback Error: &amp;quot; &lt;/span&gt;+ status);

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(errorHandler)
                    errorHandler(err, _I, xhr);

            }
        });
    }
}&lt;/pre&gt;


&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The invoke method does all the work along with the success and error handlers of the Ajax functions that fix up the result. The .invoke() method starts by encoding the input object into JSON. Notice that for WCF there’s a special flag used since WCF does not (yet?) understand ISO style date strings as dates. So a special call the JSON.stringifyWcf is made to handle this formatting scenario.&amp;#160; If you’re calling an ASMX service set isWcf=false; as ASMX services can deal with ISO dates just fine.&lt;/p&gt;

&lt;p&gt;Next the service Url is assigned. The service url points to the .SVC or .ASMX file plus the trailing slash. The method name is appended to this url which routes the method call property on the server to run the appropriate method. Next the ajax call is made. Notice that hte content type is set and all native JSON conversion is turned OFF. That’s right we need to handle the JSON conversion ourselves in order to convert dates back properly into date values via JSON.parseWithDates(). The .ajax callback handler also fixes up the response by stripping out the wrapper root object (d:) from the service response by default. If you are calling a raw REST service that doesn’t wrap results you can pass the isBare parameter as true on the invoke method. If there’s a callback handler mapped it is now called with the fixed up result.&lt;/p&gt;

&lt;p&gt;The most complex part of this component is the error handling portion that has to check for the various ways that error information is returned by the $.ajax function. The first check is made for an object in the response text which means a server error was detected and should be displayed .THat’s the easy part – it’s much harder to figure out client errors, timeouts or ‘unknown’ errors and the rest of the code in the error handler deals with this. For you as the user though you always get an object back which in my opinion is how it should be.&lt;/p&gt;

&lt;h3&gt;JSON Extensions to handle Date Encoding/Decoding&lt;/h3&gt;

&lt;p&gt;The final piece are the JSON extensions to handle date encoding/decoding on requests. This is done by extending the JSON object created by native browsers or JSON2 and adding methods that use a Replacer or Reviver object in calls to stringify or parse. Here’s what this looks like:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt;.JSON &amp;amp;&amp;amp; !&lt;span style="color: blue"&gt;this&lt;/span&gt;.JSON.parseWithDate) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;reMsAjax = /^\/Date\((d|-|.*)\)[\/|\\]$/;
    &lt;span style="color: green"&gt;// original var reMsAjax = /^\/Date\((d|-|.*)\)\/$/;

    &lt;/span&gt;JSON.parseWithDate = &lt;span style="color: blue"&gt;function&lt;/span&gt;(json) {
        &lt;span style="color: green"&gt;/// &amp;lt;summary&amp;gt;
        /// parses a JSON string and turns ISO or MSAJAX date strings
        /// into native JS date objects
        /// &amp;lt;/summary&amp;gt;    
        /// &amp;lt;param name=&amp;quot;json&amp;quot; type=&amp;quot;var&amp;quot;&amp;gt;json with dates to parse&amp;lt;/param&amp;gt;        
        /// &amp;lt;/param&amp;gt;
        /// &amp;lt;returns type=&amp;quot;value, array or object&amp;quot; /&amp;gt;
        &lt;/span&gt;&lt;span style="color: blue"&gt;try &lt;/span&gt;{
            &lt;span style="color: blue"&gt;var &lt;/span&gt;res = JSON.parse(json,
            &lt;span style="color: blue"&gt;function&lt;/span&gt;(key, value) {
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;typeof &lt;/span&gt;value === &lt;span style="color: #a31515"&gt;'string'&lt;/span&gt;) {
                    &lt;span style="color: blue"&gt;var &lt;/span&gt;a = reISO.exec(value);
                    &lt;span style="color: blue"&gt;if &lt;/span&gt;(a)
                        &lt;span style="color: blue"&gt;return new &lt;/span&gt;Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));
                    a = reMsAjax.exec(value);
                    &lt;span style="color: blue"&gt;if &lt;/span&gt;(a) {
                        &lt;span style="color: blue"&gt;var &lt;/span&gt;b = a[1].split(/[-+,.]/);
                        &lt;span style="color: blue"&gt;return new &lt;/span&gt;Date(b[0] ? +b[0] : 0 - +b[1]);
                    }
                }
                &lt;span style="color: blue"&gt;return &lt;/span&gt;value;
            });
            &lt;span style="color: blue"&gt;return &lt;/span&gt;res;
        } &lt;span style="color: blue"&gt;catch &lt;/span&gt;(e) {
            &lt;span style="color: green"&gt;// orignal error thrown has no error message so rethrow with message
            &lt;/span&gt;&lt;span style="color: blue"&gt;throw new &lt;/span&gt;Error(&lt;span style="color: #a31515"&gt;&amp;quot;JSON content could not be parsed&amp;quot;&lt;/span&gt;);
            &lt;span style="color: blue"&gt;return null&lt;/span&gt;;
        }
    };
    JSON.stringifyWcf = &lt;span style="color: blue"&gt;function&lt;/span&gt;(json) {
        &lt;span style="color: green"&gt;/// &amp;lt;summary&amp;gt;
        /// Wcf specific stringify that encodes dates in the
        /// a WCF compatible format (&amp;quot;/Date(9991231231)/&amp;quot;)
        /// Note: this format works ONLY with WCF. 
        ///       ASMX can use ISO dates as of .NET 3.5 SP1
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&amp;quot;key&amp;quot; type=&amp;quot;var&amp;quot;&amp;gt;property name&amp;lt;/param&amp;gt;    
        /// &amp;lt;param name=&amp;quot;value&amp;quot; type=&amp;quot;var&amp;quot;&amp;gt;value of the property&amp;lt;/param&amp;gt;            
        &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;JSON.stringify(json, &lt;span style="color: blue"&gt;function&lt;/span&gt;(key, value) {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;typeof &lt;/span&gt;value == &lt;span style="color: #a31515"&gt;&amp;quot;string&amp;quot;&lt;/span&gt;) {
                &lt;span style="color: blue"&gt;var &lt;/span&gt;a = reISO.exec(value);
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(a) {
                    &lt;span style="color: blue"&gt;var &lt;/span&gt;val = &lt;span style="color: #a31515"&gt;'/Date(' &lt;/span&gt;+ &lt;span style="color: blue"&gt;new &lt;/span&gt;Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])).getTime() + &lt;span style="color: #a31515"&gt;')/'&lt;/span&gt;;
                    &lt;span style="color: blue"&gt;this&lt;/span&gt;[key] = val;
                    &lt;span style="color: blue"&gt;return &lt;/span&gt;val;
                }
            }
            &lt;span style="color: blue"&gt;return &lt;/span&gt;value;
        })
    };
}&lt;/pre&gt;


&lt;p&gt;The parse() function looks for a regEx match on string values that matches either an ISO or MS Ajax style string. If found that string is parsed into a date value and converted into a date using this Reviver function. &lt;/p&gt;

&lt;p&gt;The stringifyWcf() function looks for strings that match the ISO signature. Unfortunatey JSON first turns the date into an ISO date THEN makes the Replacer function. This means the ISO string needs to be parsed into a string first then back into a date. Yuk. Further JSON quote()s the string AFTER it has been converted so it’s actually IMPOSSIBLE to create &amp;quot;\/Date(90232312)\/&amp;quot; style strings in the output. Natch.&lt;/p&gt;

&lt;p&gt;By pure luck though I discovered that WCF also supports dates in the format of: &amp;quot;/Date(232133993)/&amp;quot; and that is exactly what the code above does. Lucked out on that one and I wouldn’t be surprised if this is actually an undocumented hack the WCF team added for just this scenario. If it wasn’t for this deviant behavior JSON extension wouldn’t be possible for the full MS Ajax style date (AFAIK) short of creating a custom JSON encoder and forfeiting the native JSON parsers completely.&lt;/p&gt;

&lt;p&gt;Ultimately the best solution to this issue will be for WCF supporting ISO string date formats the same way the JavaScript serializer does. &lt;/p&gt;

&lt;p&gt;And that’s it.&lt;/p&gt;

&lt;p&gt;All of this looks pretty complicated but it’s really not – the whole thing is wrapped in a single ServiceProxy.js file so you can just include that in your project and off you go making service calls. You’ll also need jQuery loaded of course before this ServiceProxy.js since it depends on jQuery for the Ajax callbacks. If you’re using the West Wind &lt;a href="http://www.west-wind.com/westwindwebtoolkit/" target="WebToolkit"&gt;West Wind Web Toolkit&lt;/a&gt; or ww.jquery.js this functionality is already baked into it as well so no need for a separate add of the ServiceProxy.js.&lt;/p&gt;

&lt;h3&gt;Why does this matter?&lt;/h3&gt;

&lt;p&gt;Now, if you’re using Microsoft ASP.NET AJAX with Web Forms and a ScriptManager you’re probably thinking: WTF? This is a big hassle. And yes, this is more work than using a ScriptReference. In fact if you already use ASP.NET AJAX in your application go ahead and use that by all means – it’s easier to use the premade proxy and doesn’t add any additional overhead.&lt;/p&gt;

&lt;p&gt;However, more and more there are situations where ScriptManager is not available. MVC applications for example – there’s no ScriptManager and no script references and the closest thing in Microsoft Ajax is &lt;a href="http://www.asp.net/ajax/documentation/live/clientreference/Sys.Net/WebServiceProxyClass/WebServiceProxyInvokeMethod.aspx"&gt;Sys.Net.WebServiceProxy.invoke&lt;/a&gt;&amp;#160; which is very similar in fact to this service proxy (but then one look at this API makes me ill :-}).&amp;#160; Or you may simply eschew use of ASP.NET AJAX in general and prefer using only jQuery (or some other library). No need to add ASP.NET AJAX into the mix if it’s just for Web Service calls.&lt;/p&gt;

&lt;p&gt;Also keep in mind that there are alternatives to calling WCF/ASMX services. In MVC you might just use plain POST values to send data to the server and use a JsonResult() response. You can also rig something similar with any WebForms page that accepts POST. Or you can use the AjaxMethodCallback control in the &lt;a href="http://www.west-wind.com/westwindwebtoolkit/" target="WebToolkit"&gt;West Wind Web Toolkit&lt;/a&gt; (links below) which allow page, control or HttpHandler callbacks a little more transparently.&lt;/p&gt;

&lt;p&gt;However, personally I still prefer using a completely separate service or component (whether it’s WCF, &lt;a href="http://www.west-wind.com/westwindwebtoolkit/" target="WebToolkit"&gt;West Wind Web Toolkit&lt;/a&gt; or an MVC Controller specific to Ajax Callbacks) rather than mixing UI and data calls into Page processing logic. But – you can do it either way.&lt;/p&gt;

&lt;p&gt;Choices are good and this gives the &lt;strong&gt;you&lt;/strong&gt; the freedom to decide how to handle calls. Even if you’re not using the ServiceProxy for WCF callbacks, I think you might find the $.ajax() wrapper code useful as this really applies to any kind of XHR call to the server – error handling and JSON parsing apply regardless of which technology you use on the server.&lt;/p&gt;

&lt;h3&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/images/200901/ServiceProxy.zip"&gt;&lt;strong&gt;ServiceProxy.zip&lt;/strong&gt;&lt;/a&gt; 

    &lt;br /&gt;Package that contains ScriptProxy.js and ScriptProxy.min.js which contains ScriptProxy,JSON2, and the JSON extensions described above. 

    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.west-wind.com:8080/svn/WestwindWebToolkit/trunk/Westwind.Web/Resources/ww.jquery.js"&gt;&lt;strong&gt;ww.jquery.js&lt;/strong&gt;&lt;/a&gt; 

    &lt;br /&gt;West Wind jQuery extensions also include all of the above functionality plus a bunch of other commonly used plugins and utility functions. It’s bigger (about 20k compressed) but includes a ton of functionality (&lt;a href="http://www.west-wind.com/WestwindWebToolkit/docs/_2hh0s4zli.htm"&gt;docs&lt;/a&gt;). 

    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.west-wind.com/files/conferences/jquery.zip"&gt;&lt;strong&gt;Samples from jQuery Presentation&lt;/strong&gt;&lt;/a&gt; 

    &lt;br /&gt;The sample discussed is included in these samples as BasicWcfService.aspx. Includes the serviceProxy.js and ww.jquery.js files. &lt;/li&gt;
&lt;/ul&gt;&lt;div style='margin: 10px 0px'&gt;&lt;small&gt;© Rick Strahl, West Wind Technologies, 2005-2009&lt;/small&gt;&lt;/div&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/Weblog/ShowPosts.aspx?Category= ASP.NET'&gt; ASP.NET&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=jQuery'&gt;jQuery&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/Weblog/ShowPosts.aspx?Category=JavaScript'&gt;JavaScript&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style='margin-top: 5px;'&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f896411.aspx&amp;title=Making++jQuery+calls+to+WCF%2fASMX+with+a+ServiceProxy+Client"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f896411.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Zozu7rDvFAg:vmqiqi50SPc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Zozu7rDvFAg:vmqiqi50SPc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Zozu7rDvFAg:vmqiqi50SPc:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Zozu7rDvFAg:vmqiqi50SPc:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Zozu7rDvFAg:vmqiqi50SPc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Zozu7rDvFAg:vmqiqi50SPc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Zozu7rDvFAg:vmqiqi50SPc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=Zozu7rDvFAg:vmqiqi50SPc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=Zozu7rDvFAg:vmqiqi50SPc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/Zozu7rDvFAg" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/896411.aspx</feedburner:origLink></item>
  </channel>
</rss>
