<?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>Sun, 22 Nov 2009 19:39:56 GMT</pubDate>
    <lastBuildDate>Wed, 18 Nov 2009 12:54:20 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>DevConnections Slides and Samples Posted</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/AtgIRVovnGQ/77040.aspx</link>
      <guid isPermaLink="false">77040_200911181254</guid>
      <pubDate>Wed, 18 Nov 2009 12:54:20 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/77040.aspx#Comments</comments>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=77040</wfw:commentRss>
      <category> ASP.NET</category>
      <description>&lt;p&gt;I’ve posted the slides and samples to my DevConnections Sessions for anyone interested. I had a lot of fun with my sessions this time around mainly because the sessions picked were a little off the beaten track (well, the handlers/modules and e-commerce sessions anyway). For those of you that attended I hope you found the sessions useful. For the rest of you – you can check out the slides and samples if you like. Here’s what was covered:&lt;/p&gt;  &lt;h3&gt;Introduction to jQuery with ASP.NET&lt;/h3&gt;  &lt;p&gt;This session covered mostly the client side of jQuery demonstrated on a small sample page with a variety of incrementally built up examples of selection and page manipulation. This session also introduces some of the basics of AJAX communication talking to ASP.NET. When I do this session it never turns out exactly the same way and this time around the examples were on the more basic side and purely done with hands on demonstrations rather than walk throughs of more complex examples. Alas this session always feels like it needs another half an hour to get through the full sortiment of functionality. The slides and samples cover a wider variety of topics and there are many examples that demonstrate more advanced operations like interacting with WCF REST services, using client templating and building rich client only windowed interfaces.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.west-wind.com/files/conferences/jquery.zip" target="_blank"&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Low Level ASP.NET: Handlers and Modules&lt;/h3&gt;  &lt;p&gt;This session was a look at the ASP.NET pipeline and it discusses some of the ASP.NET base architecture and key components from HttpRuntime on up through the various modules and handlers that make up the ASP.NET/IIS pipeline. This session is fun as there are a number of cool examples that demonstrate the power and flexibility of ASP.NET, but some of the examples were external and interfacing with other technologies so they’re not actually included in the downloadable samples. However, there are still a few cool ones in there – there’s an image resizing handler, an image overlay module that stamps images with Sample if loaded from a certain folder, an OpenID authentication module (which failed during the demo due to the crappy internet connection at DevConnections this year :-}), Response filtering using a generic filter stream component, a generic error handler and a few others. The slides cover a lot of the ASP.NET pipeline flow and various HttpRuntime components.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.west-wind.com/files/conferences/conn_HandlersAndModules.zip" target="_blank"&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Electronic Payment Processing in ASP.NET Applications&lt;/h3&gt;  &lt;p&gt;This session covered the business end and integration of electronic credit card processing and PayPal. A good part of this session deals with what’s involved in payment processing, getting signed up and who you have to deal with for your merchant account. We then took a look at integration of credit card processing via some generic components provided with the session that allow processing using a unified class interface with specific implementations for several of the most common gateway providers including Authorize.NET, PayFlowPro, LinkPoint, BluePay etc. We also briefly looked at PayPal Classic implementation which provides a quick and cheap if not quite as professional mechanism for taking payments online. The samples provide the Credit Card processing wrappers for the various gateway providers as well as a PayPal helper class to generate the PayPal redirect urls as well as helper code for dealing with IPN callbacks.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.west-wind.com/files/conferences/electronicpayment.zip" target="_blank"&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hope some of you will find the material useful. Enjoy.&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;/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%2f77040.aspx&amp;title=DevConnections+Slides+and+Samples+Posted"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f77040.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=ac59a8bf&amp;t=633945155962440000' target='_top'&gt;&lt;img src='http://www.west-wind.com/banners/WestwindWebToolkit.jpg' border='0'&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AtgIRVovnGQ:d35TfduBSM4: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=AtgIRVovnGQ:d35TfduBSM4: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=AtgIRVovnGQ:d35TfduBSM4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=AtgIRVovnGQ:d35TfduBSM4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AtgIRVovnGQ:d35TfduBSM4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=AtgIRVovnGQ:d35TfduBSM4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AtgIRVovnGQ:d35TfduBSM4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=AtgIRVovnGQ:d35TfduBSM4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=AtgIRVovnGQ:d35TfduBSM4: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/AtgIRVovnGQ" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/77040.aspx</feedburner:origLink></item>
    <item>
      <title>Capturing and Transforming ASP.NET Output with Response.Filter</title>
      <link>http://feedproxy.google.com/~r/RickStrahl/~3/A8dhMSnQj10/72596.aspx</link>
      <guid isPermaLink="false">72596_200911131747</guid>
      <pubDate>Fri, 13 Nov 2009 17:47:39 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/72596.aspx#Comments</comments>
      <slash:comments>11</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=72596</wfw:commentRss>
      <category>ASP.NET</category>
      <description>&lt;p&gt;During one of my Handlers and Modules session at DevConnections this week one of the attendees asked a question that I didn’t have an immediate answer for. Basically he wanted to capture response output completely and then apply some filtering to the output – effectively injecting some additional content into the page AFTER the page had completely rendered. Specifically the output should be captured from anywhere – not just a page and have this code injected into the page.&lt;/p&gt;  &lt;p&gt;Some time ago I posted some code that &lt;a href="http://www.west-wind.com/weblog/posts/481.aspx" target="_blank"&gt;allows you to capture ASP.NET Page output&lt;/a&gt; by overriding the Render() method, capturing the HtmlTextWriter() and reading its content, modifying the rendered data as text then writing it back out. I’ve actually used this approach on a few occasions and it works fine for ASP.NET pages. But this obviously won’t work outside of the Page class environment and it’s not really generic – you have to create a custom page class in order to handle the output capture.&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000" size="1"&gt;[updated 11/16/2009 – updated ResponseFilterStream implementation and a few additional notes based on comments]&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;Enter Response.Filter&lt;/h3&gt;  &lt;p&gt;However, ASP.NET includes a Response.Filter which can be used – well to filter output. Basically Response.Filter is a stream through which the OutputStream is piped back to the Web Server (indirectly). As content is written into the Response object, the filter stream receives the appropriate Stream commands like Write, Flush and Close as well as read operations although for a Response.Filter that’s uncommon to be hit. The Response.Filter can be programmatically replaced at runtime which allows you to effectively intercept all output generation that runs through ASP.NET.&lt;/p&gt;  &lt;h3&gt;A common Example: Dynamic GZip Encoding&lt;/h3&gt;  &lt;p&gt;A rather common use of Response.Filter hooking up code based, dynamic&amp;#160; GZip compression for requests which is dead simple by applying a &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx" target="_blank"&gt;GZipStream&lt;/a&gt; (or &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.compression.deflatestream.aspx" target="_blank"&gt;DeflateStream&lt;/a&gt;) to Response.Filter. The following generic routines can be used very easily to detect GZip capability of the client and compress response output with a single line of code and a couple of library helper routines:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;WebUtils&lt;/span&gt;.GZipEncodePage();&lt;/pre&gt;
which is handled with a few lines of reusable code and a couple of static helper methods: 

&lt;br /&gt;

&lt;br /&gt;&lt;span style="color: gray"&gt;&lt;font face="Courier New"&gt;/// &amp;lt;summary&amp;gt; 
    &lt;br /&gt;///&lt;/font&gt;&lt;/span&gt;&lt;font face="Courier New"&gt;&lt;span style="color: green"&gt;Sets up the current page or handler to use GZip through a Response.Filter 
    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;span style="color: green"&gt;IMPORTANT:&amp;#160; &lt;br /&gt;&lt;/span&gt;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;/font&gt;&lt;span style="color: green"&gt;&lt;font face="Courier New"&gt;You have to call this method before any output is generated! 
    &lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;font face="Courier New"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt; 
    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;public static void &lt;/span&gt;GZipEncodePage() 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;HttpResponse &lt;/span&gt;Response = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Response; 

  &lt;br /&gt;

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt;(IsGZipSupported()) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;string&lt;/span&gt;AcceptEncoding = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Request.Headers[&lt;span style="color: #a31515"&gt;&amp;quot;Accept-Encoding&amp;quot;&lt;/span&gt;]; 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt;(AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;&amp;quot;deflate&amp;quot;&lt;/span&gt;)) 

  &lt;br /&gt;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Response.Filter = &lt;span style="color: blue"&gt;new&lt;/span&gt;System.IO.Compression.&lt;span style="color: #2b91af"&gt;DeflateStream&lt;/span&gt;(Response.Filter, 

  &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;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.Compression.&lt;span style="color: #2b91af"&gt;CompressionMode&lt;/span&gt;.Compress); 

  &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; Response.AppendHeader(&lt;span style="color: #a31515"&gt;&amp;quot;Content-Encoding&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;deflate&amp;quot;&lt;/span&gt;); 

  &lt;br /&gt;&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;span style="color: blue"&gt;else 
    &lt;br /&gt;&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; Response.Filter = &lt;span style="color: blue"&gt;new&lt;/span&gt;System.IO.Compression.&lt;span style="color: #2b91af"&gt;GZipStream&lt;/span&gt;(Response.Filter, 

  &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;&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;&amp;#160;&amp;#160;&amp;#160; System.IO.Compression.&lt;span style="color: #2b91af"&gt;CompressionMode&lt;/span&gt;.Compress); 

  &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; Response.AppendHeader(&lt;span style="color: #a31515"&gt;&amp;quot;Content-Encoding&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;gzip&amp;quot;&lt;/span&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;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } 

  &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;// Allow proxy servers to cache encoded and unencoded versions separately 
    &lt;br /&gt;&amp;#160;&amp;#160; &lt;/span&gt;Response.AppendHeader(&lt;span style="color: #a31515"&gt;&amp;quot;Vary&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Content-Encoding&amp;quot;&lt;/span&gt;); 

  &lt;br /&gt;}&lt;/font&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;Determines if GZip is supported
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public static bool &lt;/span&gt;IsGZipSupported()
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;AcceptEncoding = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Request.Headers[&lt;span style="color: #a31515"&gt;&amp;quot;Accept-Encoding&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(AcceptEncoding) &amp;amp;&amp;amp;
         (AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;&amp;quot;gzip&amp;quot;&lt;/span&gt;) || AcceptEncoding.Contains(&lt;span style="color: #a31515"&gt;&amp;quot;deflate&amp;quot;&lt;/span&gt;)))
        &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;GZipStream and DeflateStream are streams that are assigned to Response.Filter and by doing so apply the appropriate compression on the active Response.&lt;/p&gt;

&lt;h3&gt;Response.Filter content is chunked&lt;/h3&gt;

&lt;p&gt;So to implement a Response.Filter effectively requires only that you implement a custom stream and handle the Write() method to capture Response output as it’s written. At first blush this seems very simple – you capture the output in Write, transform it and write out the transformed content in one pass. And that indeed works for small amounts of content. But you see, the problem is that output is written in small buffer chunks (a little less than 16k it appears) rather than just a single Write() statement into the stream, which makes perfect sense for ASP.NET to stream data back to IIS in smaller chunks to minimize memory usage en route.&lt;/p&gt;

&lt;p&gt;Unfortunately this also makes it a more difficult to implement any filtering routines since you don’t directly get access to all of the response content which is problematic especially if those filtering routines require you to look at the ENTIRE response in order to transform or capture the output as is needed for the solution the gentleman in my session asked for.&lt;/p&gt;

&lt;p&gt;So in order to address this a slightly different approach is required that basically captures all the Write() buffers passed into a cached stream and then making the stream available only when it’s complete and ready to be flushed. &lt;/p&gt;

&lt;p&gt;As I was thinking about the implementation I also started thinking about the few instances when I’ve used Response.Filter implementations. Each time I had to create a new Stream subclass and create my custom functionality but in the end each implementation did the same thing – capturing output and transforming it. I thought there should be an easier way to do this by creating a re-usable Stream class that can handle stream transformations that are common to Response.Filter implementations.&lt;/p&gt;

&lt;h3&gt;Creating a semi-generic Response Filter Stream Class&lt;/h3&gt;

&lt;p&gt;What I ended up with is a ResponseFilterStream class that provides a handful of Events that allow you to capture and/or transform Response content. The class implements a subclass of &lt;em&gt;Stream&lt;/em&gt; and then overrides Write() and Flush() to handle capturing and transformation operations. By exposing events it’s easy to hook up capture or transformation operations via single focused methods.&lt;/p&gt;

&lt;p&gt;ResponseFilterStream exposes the following events:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;CaptureStream, CaptureString 
      &lt;br /&gt;&lt;/strong&gt;Captures the output only and provides either a MemoryStream or String with the final page output. Capture is hooked to the Flush() operation of the stream. 

    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;TransformStream, TransformString 
      &lt;br /&gt;&lt;/strong&gt;Allows you to transform the complete response output with events that receive a MemoryStream or String respectively and can you modify the output then return it back as a return value. The transformed output is then written back out in a single chunk to the response output stream. These events capture all output internally first then write the entire buffer into the response.

    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;TransformWrite, TransformWriteString&lt;/strong&gt; 

    &lt;br /&gt;Allows you to transform the Response data as it is written in its original chunk size in the Stream’s Write() method. Unlike TransformStream/TransformString which operate on the complete output, these events only see the current chunk of data written. This is more efficient as there’s no caching involved, but can cause problems due to searched content splitting over multiple chunks. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using this implementation, creating a custom Response.Filter transformation becomes as simple as the following code.&lt;/p&gt;

&lt;p&gt;To hook up the Response.Filter using the MemoryStream version event:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ResponseFilterStream &lt;/span&gt;filter = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ResponseFilterStream&lt;/span&gt;(Response.Filter);
filter.TransformStream += filter_TransformStream;
Response.Filter = filter;  &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;and the event handler to do the transformation:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;filter_TransformStream(&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;ms)
{
    &lt;span style="color: #2b91af"&gt;Encoding &lt;/span&gt;encoding = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Response.ContentEncoding;
    
    &lt;span style="color: blue"&gt;string &lt;/span&gt;output = encoding.GetString(ms.ToArray());

    output = FixPaths(output);
    
    ms = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;(output.Length);

    &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] buffer = encoding.GetBytes(output);
    ms.Write(buffer,0,buffer.Length);

    &lt;span style="color: blue"&gt;return &lt;/span&gt;ms;
}&lt;br /&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private string &lt;/span&gt;FixPaths(&lt;span style="color: blue"&gt;string &lt;/span&gt;output)
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;path = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Request.ApplicationPath;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: green"&gt;// override root path wonkiness
    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(path == &lt;span style="color: #a31515"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;)
        path = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;

    output = output.Replace(&lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;~/&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;\&amp;quot;&amp;quot; &lt;/span&gt;+ path + &lt;span style="color: #a31515"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;).Replace(&lt;span style="color: #a31515"&gt;&amp;quot;'~/&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;'&amp;quot; &lt;/span&gt;+ path + &lt;span style="color: #a31515"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;return &lt;/span&gt;output;
}&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;The idea of the event handler is that you can do whatever you want to the stream and return back a stream – either the same one that’s been modified or a brand new one – which is then sent back to as the final response.&lt;/p&gt;

&lt;p&gt;The above code can be simplified even more by using the string version events which handle the stream to string conversions for you: &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ResponseFilterStream &lt;/span&gt;filter = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ResponseFilterStream&lt;/span&gt;(Response.Filter);
filter.TransformString += filter_TransformString;
Response.Filter = filter;                &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;and the event handler to do the transformation calling the same FixPaths method shown above:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;filter_TransformString(&lt;span style="color: blue"&gt;string &lt;/span&gt;output)
{
    &lt;span style="color: blue"&gt;return &lt;/span&gt;FixPaths(output);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The events for capturing output and capturing and transforming chunks work in a very similar way. By using events to handle the transformations ResponseFilterStream becomes a reusable component and we don’t have to create a new stream class or subclass an existing Stream based classed. &lt;/p&gt;

&lt;p&gt;By the way, the example used here is kind of a cool trick which transforms “~/” expressions inside of the final generated HTML output – even in plain HTML controls not HTML controls – and transforms them into the appropriate application relative path in the same way that ResolveUrl would do.&lt;/p&gt;

&lt;p&gt;So you can write plain old HTML like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&amp;lt;a href=”~/default.aspx”&amp;gt;Home&amp;lt;/a&amp;gt;&lt;/strong&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;and have it turned into: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;strong&gt;&amp;lt;a href=”/myVirtual/default.aspx”&amp;gt;Home&amp;lt;/a&amp;gt;&lt;/strong&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;without having to use an ASP.NET control like Hyperlink or Image or having to constantly use:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&amp;lt;img src=”&amp;lt;%= ResolveUrl(“~/images/home.gif”) %&amp;gt;” /&amp;gt; 
    &lt;br /&gt;&lt;/strong&gt;

  &lt;br /&gt;in MVC applications (which frankly is one of the most annoying things about MVC especially given the path hell that extension-less and endpoint-less URLs impose). 

  &lt;br /&gt;

  &lt;br /&gt;I can’t take credit for this idea. While discussing the Response.Filter issues on Twitter a hint from &lt;a href="http://twitter.com/dylanbeattie/status/5635996264" target="_blank"&gt;Dylan Beattie&lt;/a&gt; who pointed me at one of his examples which does something similar. I thought the idea was cool enough to use an example for future demos of Response.Filter functionality in ASP.NET next I time I do the Modules and Handlers talk (which was great fun BTW). 

  &lt;br /&gt;

  &lt;br /&gt;How practical this is is debatable however since there’s definitely some overhead to using a Response.Filter in general and especially on one that caches the output and the re-writes it later. Make sure to test for performance anytime you use Response.Filter hookup and make sure it' doesn’t end up killing perf on you. You’ve been warned :-}.&lt;/p&gt;

&lt;h3&gt;How does ResponseFilterStream work?&lt;/h3&gt;

&lt;p&gt;The big win of this implementation IMHO is that it’s a reusable&amp;#160; component – so for implementation there’s no new class, no subclassing – you simply attach to an event to implement an event handler method with a straight forward signature to retrieve the stream or string you’re interested in.&lt;/p&gt;

&lt;p&gt;The implementation is based on a subclass of Stream as is required in order to handle the Response.Filter requirements. What’s different than other implementations I’ve seen in various places is that it supports capturing output as a whole to allow retrieving the full response output for capture or modification. The exception are the TransformWrite and TransformWrite events which operate only active chunk of data written by the Response.&lt;/p&gt;

&lt;p&gt;For captured output, the Write() method captures output into an internal MemoryStream that is cached until writing is complete. So Write() is called when ASP.NET writes to the Response stream, but the filter doesn’t pass on the Write immediately to the filter’s internal stream. The data is cached and only when the Flush() method is called to finalize the Stream’s output do we actually send the cached stream off for transformation (if the events are hooked up) and THEN finally write out the returned content in one big chunk.&lt;/p&gt;

&lt;p&gt;Here’s the implementation of ResponseFilterStream:&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;A semi-generic Stream implementation for Response.Filter with
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;an event interface for handling Content transformations via
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;Stream or String.    
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;remarks&amp;gt;
/// &lt;/span&gt;&lt;span style="color: green"&gt;Use with care for large output as this implementation copies
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;the output into a memory stream and so increases memory usage.
&lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/remarks&amp;gt;
/// &amp;lt;/summary&amp;gt;    
&lt;/span&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ResponseFilterStream &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;Stream
&lt;/span&gt;{
    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;The original stream
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Stream &lt;/span&gt;_stream;

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Current position in the original stream
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;long &lt;/span&gt;_position;

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Stream that original content is read into
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;and then passed to TransformStream function
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;_cacheStream = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;(5000);

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Internal pointer that that keeps track of the size
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;of the cacheStream
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;_cachePointer = 0;


    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;responseStream&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;ResponseFilterStream(&lt;span style="color: #2b91af"&gt;Stream &lt;/span&gt;responseStream)
    {
        _stream = responseStream;
    }


    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Determines whether the stream is captured
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private bool &lt;/span&gt;IsCaptured
    {
        &lt;span style="color: blue"&gt;get 
        &lt;/span&gt;{

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(CaptureStream != &lt;span style="color: blue"&gt;null &lt;/span&gt;|| CaptureString != &lt;span style="color: blue"&gt;null &lt;/span&gt;||
                TransformStream != &lt;span style="color: blue"&gt;null &lt;/span&gt;|| TransformString != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                &lt;span style="color: blue"&gt;return true&lt;/span&gt;;

            &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
        }
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Determines whether the Write method is outputting data immediately
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;or delaying output until Flush() is fired.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;private bool &lt;/span&gt;IsOutputDelayed
    {
        &lt;span style="color: blue"&gt;get 
        &lt;/span&gt;{
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(TransformStream != &lt;span style="color: blue"&gt;null &lt;/span&gt;|| TransformString != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
                &lt;span style="color: blue"&gt;return true&lt;/span&gt;;

            &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
        }        
    }
    

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Event that captures Response output and makes it available
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;as a MemoryStream instance. Output is captured but won't 
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;affect Response output.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public event &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;&amp;gt; CaptureStream;

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Event that captures Response output and makes it available
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;as a string. Output is captured but won't affect Response output.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public event &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; CaptureString;

    

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Event that allows you transform the stream as each chunk of
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;the output is written in the Write() operation of the stream.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;This means that that it's possible/likely that the input 
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;buffer will not contain the full response output but only
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;one of potentially many chunks.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// 
    /// &lt;/span&gt;&lt;span style="color: green"&gt;This event is called as part of the filter stream's Write() 
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;operation.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&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: blue"&gt;byte&lt;/span&gt;[], &lt;span style="color: blue"&gt;byte&lt;/span&gt;[]&amp;gt; TransformWrite;


    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Event that allows you to transform the response stream as
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;each chunk of bytep[] output is written during the stream's write
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;operation. This means it's possibly/likely that the string
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;passed to the handler only contains a portion of the full
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;output. Typical buffer chunks are around 16k a piece.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// 
    /// &lt;/span&gt;&lt;span style="color: green"&gt;This event is called as part of the stream's Write operation.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&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: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; TransformWriteString;

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;This event allows capturing and transformation of the entire 
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;output stream by caching all write operations and delaying final
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;response output until Flush() is called on the stream.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&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;MemoryStream&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;&amp;gt; TransformStream;

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Event that can be hooked up to handle Response.Filter
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;Transformation. Passed a string that you can modify and
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;return back as a return value. The modified content
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;will become the final output.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&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: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; TransformString;


    &lt;span style="color: blue"&gt;protected virtual void &lt;/span&gt;OnCaptureStream(&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;ms)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(CaptureStream != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            CaptureStream(ms);
    }


    &lt;span style="color: blue"&gt;private void &lt;/span&gt;OnCaptureStringInternal(&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;ms)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(CaptureString != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
        {
            &lt;span style="color: blue"&gt;string &lt;/span&gt;content = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Response.ContentEncoding.GetString(ms.ToArray());
            OnCaptureString(content);
        }
    }

    &lt;span style="color: blue"&gt;protected virtual void &lt;/span&gt;OnCaptureString(&lt;span style="color: blue"&gt;string &lt;/span&gt;output)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(CaptureString != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            CaptureString(output);
    }

    &lt;span style="color: blue"&gt;protected virtual byte&lt;/span&gt;[] OnTransformWrite(&lt;span style="color: blue"&gt;byte&lt;/span&gt;[] buffer)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(TransformWrite != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;TransformWrite(buffer);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;buffer;
    }

    &lt;span style="color: blue"&gt;private byte&lt;/span&gt;[] OnTransformWriteStringInternal(&lt;span style="color: blue"&gt;byte&lt;/span&gt;[] buffer)
    {
        &lt;span style="color: #2b91af"&gt;Encoding &lt;/span&gt;encoding = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Response.ContentEncoding;
        &lt;span style="color: blue"&gt;string &lt;/span&gt;output = OnTransformWriteString(encoding.GetString(buffer));
        &lt;span style="color: blue"&gt;return &lt;/span&gt;encoding.GetBytes(output);
    }

    &lt;span style="color: blue"&gt;private string &lt;/span&gt;OnTransformWriteString(&lt;span style="color: blue"&gt;string &lt;/span&gt;value)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(TransformWriteString != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;TransformWriteString(value);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;value;
    }


    &lt;span style="color: blue"&gt;protected virtual &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;OnTransformCompleteStream(&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;ms)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(TransformStream != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;TransformStream(ms);

        &lt;span style="color: blue"&gt;return &lt;/span&gt;ms;
    }




    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Allows transforming of strings
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// 
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Note this handler is internal and not meant to be overridden
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;as the TransformString Event has to be hooked up in order
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;for this handler to even fire to avoid the overhead of string
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;conversion on every pass through.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;responseText&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;private string &lt;/span&gt;OnTransformCompleteString(&lt;span style="color: blue"&gt;string &lt;/span&gt;responseText)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(TransformString != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            TransformString(responseText);

        &lt;span style="color: blue"&gt;return &lt;/span&gt;responseText;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Wrapper method form OnTransformString that handles
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;stream to string and vice versa conversions
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;ms&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;internal &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;OnTransformCompleteStringInternal(&lt;span style="color: #2b91af"&gt;MemoryStream &lt;/span&gt;ms)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(TransformString == &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            &lt;span style="color: blue"&gt;return &lt;/span&gt;ms;

        &lt;span style="color: green"&gt;//string content = ms.GetAsString();
        &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;content = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Response.ContentEncoding.GetString(ms.ToArray());

        content = TransformString(content);
        &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] buffer = &lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Response.ContentEncoding.GetBytes(content);
        ms = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;();
        ms.Write(buffer, 0, buffer.Length);
        &lt;span style="color: green"&gt;//ms.WriteString(content);

        &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;ms;
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override bool &lt;/span&gt;CanRead
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return true&lt;/span&gt;; }
    }

    &lt;span style="color: blue"&gt;public override bool &lt;/span&gt;CanSeek
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return true&lt;/span&gt;; }
    }
    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override bool &lt;/span&gt;CanWrite
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return true&lt;/span&gt;; }
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override long &lt;/span&gt;Length
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;0; }
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override long &lt;/span&gt;Position
    {
        &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;_position; }
        &lt;span style="color: blue"&gt;set &lt;/span&gt;{ _position = &lt;span style="color: blue"&gt;value&lt;/span&gt;; }
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;offset&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;direction&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 override long &lt;/span&gt;Seek(&lt;span style="color: blue"&gt;long &lt;/span&gt;offset, System.IO.&lt;span style="color: #2b91af"&gt;SeekOrigin &lt;/span&gt;direction)
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_stream.Seek(offset, direction);
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;length&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override void &lt;/span&gt;SetLength(&lt;span style="color: blue"&gt;long &lt;/span&gt;length)
    {
        _stream.SetLength(length);
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override void &lt;/span&gt;Close()
    {
        _stream.Close();
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Override flush by writing out the cached stream data
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override void &lt;/span&gt;Flush()
    {

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(IsCaptured &amp;amp;&amp;amp; _cacheStream.Length &amp;gt; 0)
        {
            &lt;span style="color: green"&gt;// Check for transform implementations
            &lt;/span&gt;_cacheStream = OnTransformCompleteStream(_cacheStream);
            _cacheStream = OnTransformCompleteStringInternal(_cacheStream);
            
            OnCaptureStream(_cacheStream);
            OnCaptureStringInternal(_cacheStream);

            &lt;span style="color: green"&gt;// write the stream back out if output was delayed
            &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(IsOutputDelayed)
                _stream.Write(_cacheStream.ToArray(), 0, (&lt;span style="color: blue"&gt;int&lt;/span&gt;)_cacheStream.Length);

            &lt;span style="color: green"&gt;// Clear the cache once we've written it out
            &lt;/span&gt;_cacheStream.SetLength(0);
        }

        &lt;span style="color: green"&gt;// default flush behavior
        &lt;/span&gt;_stream.Flush();
    }

    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;buffer&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;offset&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;count&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 override int &lt;/span&gt;Read(&lt;span style="color: blue"&gt;byte&lt;/span&gt;[] buffer, &lt;span style="color: blue"&gt;int &lt;/span&gt;offset, &lt;span style="color: blue"&gt;int &lt;/span&gt;count)
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_stream.Read(buffer, offset, count);
    }


    &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color: green"&gt;Overriden to capture output written by ASP.NET and captured
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;into a cached stream that is written out later when Flush()
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;is called.
    &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;buffer&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;offset&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;count&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color: blue"&gt;public override void &lt;/span&gt;Write(&lt;span style="color: blue"&gt;byte&lt;/span&gt;[] buffer, &lt;span style="color: blue"&gt;int &lt;/span&gt;offset, &lt;span style="color: blue"&gt;int &lt;/span&gt;count)
    {
        &lt;span style="color: blue"&gt;if &lt;/span&gt;( IsCaptured )
        {
            &lt;span style="color: green"&gt;// copy to holding buffer only - we'll write out later
            &lt;/span&gt;_cacheStream.Write(buffer, 0, count);
            _cachePointer += count;
        }

        &lt;span style="color: green"&gt;// just transform this buffer
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(TransformWrite != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            buffer = OnTransformWrite(buffer);
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(TransformWriteString != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            buffer = OnTransformWriteStringInternal(buffer);

        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!IsOutputDelayed)
            _stream.Write(buffer, offset, buffer.Length);
        
    }

}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The key features are the events and corresponding OnXXX methods that handle the event hookups, and the Write() and Flush() methods of the stream implementation. All the rest of the members tend to be plain jane passthrough stream implementation code without much consequence. &lt;/p&gt;

&lt;p&gt;I do love the way Action&amp;lt;t&amp;gt; and &lt;a href="http://www.west-wind.com/WebLog/posts/28442.aspx" target="_blank"&gt;Func&amp;lt;T&amp;gt; make it so easy to create the event signatures&lt;/a&gt; for the various events – sweet.&lt;/p&gt;

&lt;h3&gt;A few Things to consider&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Response.Filter is not great for performance in general as it adds another layer of indirection to the ASP.NET output pipeline, and this implementation in particular adds a memory hit as it basically duplicates the response output into the cached memory stream which is necessary since you may have to look at the entire response. If you have large pages in particular this can cause potentially serious memory pressure in your server application. So be careful of wholesale adoption of this (or other) Response.Filters. Make sure to do some performance testing to ensure it’s not killing your app’s performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Response.Filter works everywhere&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A few questions came up in comments and discussion as to capturing ALL output hitting the site and – yes you can definitely do that by assigning a Response.Filter inside of a module. If you do this however you’ll want to be very careful and decide which content you actually want to capture especially in IIS 7 which passes ALL content – including static images/CSS etc. through the ASP.NET pipeline. So it is important to filter only on what you’re looking for – like the page extension or maybe more effectively the Response.ContentType.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Response.Filter Chaining&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Originally I thought that filter chaining doesn’t work at all due to a bug in the stream implementation code. But it’s quite possible to assign multiple filters to the Response.Filter property. So the following actually works to both compress the output and apply the transformed content:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;strong&gt;&lt;span style="color: #2b91af"&gt;WebUtils&lt;/span&gt;.GZipEncodePage();
&lt;/strong&gt;
&lt;span style="color: #2b91af"&gt;ResponseFilterStream &lt;/span&gt;filter = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ResponseFilterStream&lt;/span&gt;(Response.Filter);
filter.TransformString += filter_TransformString;
&lt;strong&gt;Response.Filter = filter;                &lt;/strong&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;However the following &lt;strong&gt;does not&lt;/strong&gt; work resulting in invalid content encoding errors:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ResponseFilterStream &lt;/span&gt;filter = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ResponseFilterStream&lt;/span&gt;(Response.Filter);
filter.TransformString += filter_TransformString;
&lt;strong&gt;Response.Filter = filter;
&lt;/strong&gt;
&lt;strong&gt;&lt;span style="color: #2b91af"&gt;WebUtils&lt;/span&gt;.GZipEncodePage();&lt;/strong&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In other words multiple Response filters can work together but it depends entirely on the implementation whether they can be chained or in which order they can be chained. In this case running the GZip/Deflate stream filters apparently relies on the original content length of the output and chokes when the content is modified. But if attaching the compression first it works fine as unintuitive as that may seem.&lt;/p&gt;

&lt;h3&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://west-wind.com/weblog/images/200901/ResponseFilter.zip" target="_blank"&gt;Download example code&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.west-wind.com/weblog/posts/481.aspx" target="_blank"&gt;Capture Output from ASP.NET Pages&lt;/a&gt; &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;/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%2f72596.aspx&amp;title=Capturing+and+Transforming+ASP.NET+Output+with+Response.Filter"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f72596.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=ac59a8bf&amp;t=633945155962460000' target='_top'&gt;&lt;img src='http://www.west-wind.com/banners/WestwindWebToolkit.jpg' border='0'&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=A8dhMSnQj10:QgYK_BXXhw8: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=A8dhMSnQj10:QgYK_BXXhw8: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=A8dhMSnQj10:QgYK_BXXhw8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=A8dhMSnQj10:QgYK_BXXhw8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=A8dhMSnQj10:QgYK_BXXhw8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=A8dhMSnQj10:QgYK_BXXhw8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=A8dhMSnQj10:QgYK_BXXhw8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RickStrahl?i=A8dhMSnQj10:QgYK_BXXhw8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RickStrahl?a=A8dhMSnQj10:QgYK_BXXhw8: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/A8dhMSnQj10" height="1" width="1"/&gt;</description>
    <feedburner:origLink>http://west-wind.com/weblog/posts/72596.aspx</feedburner:origLink></item>
    <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>10</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;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;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;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;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;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;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>17</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;p&gt;vs the more expected:&lt;/p&gt;

&lt;pre class="code"&gt;#txtName
{
    font-weight: bold;
}&lt;/pre&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;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;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;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;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;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;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;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;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;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;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;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;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;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;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;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;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;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>13</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>29</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>20</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>14</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>2</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>
  </channel>
</rss>
