<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><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>Fri, 25 Jul 2008 14:12:16 GMT</pubDate>
    <lastBuildDate>Tue, 22 Jul 2008 20:05:01 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" /><item>
      <title>Forcing Client Windows to pop up as Windows in Tabbed Browsers</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/342859884/428973.aspx</link>
      <guid isPermaLink="false">428973_200807222005</guid>
      <pubDate>Tue, 22 Jul 2008 20:05:01 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/428973.aspx#Comments</comments>
      <slash:comments>7</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=428973</wfw:commentRss>
      <category>HTML</category>
      <category>JavaScript</category>
      <description>&lt;p&gt;By default if you open a new window in Tab based browsers like FireFox 3 or IE 7 new windows pop up in new tabs. In most situations this is the desirable behavior, but sometimes it's in fact required to get a new window to pop up on the desktop and get it activated immediately. &lt;/p&gt; &lt;p&gt;I ran into this situation today in a complex Intranet application that basically allows editing of several sets of related data simultaneously to content in the 'main' window. While I fully agree with the the school of thought that believes too many windows in Web UIs are evil, in this situation I really couldn't see good alternatives. Alternatives are opening in Tabs (not acceptable if more than one window gets opened at a time) or using DOM internal pop up windows (ala HoverPanel). The latter also isn't really acceptable as the pop up forms are rather complex and page management would get increasingly complex to manage in a single page especially since often times the SAME forms are popped up with different data. &lt;/p&gt; &lt;p&gt;So in the end I decided separate windows&amp;nbsp; are probably the best choice. It's been a while since I had last thought about this so I figured a quick window.open() would be all that's needed but as I found out, that only opens new tabs. How do you 'force' windows to open as windows rather than in a new tab?&lt;/p&gt; &lt;p&gt;As it turns out it's quite simple to do - you can specify a few&amp;nbsp; parameters in the window options to effectively force the window to pop up as a window instead of loading into a tab:&lt;/p&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; childWindows = [];&lt;br&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&lt;br&gt;&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;function&lt;/span&gt; showApplet(appletName,id)&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; win = &lt;strong&gt;window.open( String.format(&lt;span style="color: #a31515"&gt;"applet.aspx?applet={0}&amp;amp;id={1}"&lt;/span&gt;,appletName,id),&lt;br&gt;                          &lt;span style="color: #a31515"&gt;"_blank"&lt;/span&gt;,&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515"&gt;"resizable=yes,scrollbars=yes,width=800,height=600,status=yes"&lt;/span&gt; );&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp; win.focus();&amp;nbsp; &lt;span style="color: green"&gt;// force active&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp; childWindows.push(win);&amp;nbsp; &lt;span style="color: green"&gt;// save for later release&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;}&lt;br&gt;&lt;/pre&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;pre style="margin: 0px"&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Any time window.open() specifies parameters that are explicitly attributable to a 'window' - like resizable, scrollbars or height or width - the window does in fact get popped up as a window. Omit any of these window specific parameters and the window loads using the browser's default settings. Note the win.focus() which is useful in forcing the new window to be activated. This is especially useful if you create only one new window and repeatedly load content into it as these windows generally do not come to the top of the desktop window stack.&lt;/p&gt;
&lt;p&gt;Speaking of default settings, window loading can also be controlled via the browser settings. In FireFox you can specify whether to open windows in tabs or in a new window:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" alt="WindowOrTabs" src="http://www.west-wind.com/WebLog/images/200801/WindowsLiveWriter/f5263ff5a50f_93B6/WindowOrTabs_3.png" width="528" height="305"&gt; &lt;/p&gt;
&lt;p&gt;Other browsers have similar options. &lt;/p&gt;
&lt;p&gt;However, the above code snippet allows overriding these settings so there really should never be a reason to choose the Open in New Window option.&lt;/p&gt;
&lt;h3&gt;Cleaning up Opened Windows&lt;/h3&gt;
&lt;p&gt;Note that when building your own applications and forcing windows to pop up it's often also important to remove windows again when you're done with your page, or after an operation has completed. In my app scenario for example I had to close a window after some action occurred in the child window or a final Save operation occurs in the main window for example.&lt;/p&gt;
&lt;p&gt;So it's useful to keep track of windows opened in a page and then maybe even automatically close the child windows when the page is navigated off of. You'll notice in the code above that windows are stored in a childWindows array, which is done for precisely this reason. To close out all windows the following code is used:&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;function&lt;/span&gt; unloadChildWindows()&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;for&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; x=childWindows.length-1; x &amp;gt; -1; x--)&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; win = childWindows.pop();&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; win.close();&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; win = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/pre&gt;&lt;pre style="margin: 0px"&gt;}&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;$(document).ready(&lt;span style="color: blue"&gt;function&lt;/span&gt;(){&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $(window).unload( unloadChildWindows );&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/pre&gt;&lt;pre style="margin: 0px"&gt;});&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which runs through each of the child windows and closes them. If you want to automatically close all windows when the page is closed or navigated off of you also hook the window.unload event and fire this function - here using jQuery to fire the event and route it to the function.&lt;/p&gt;
&lt;p&gt;All that said, it shouldn't be often that you need to pop up windows on a Web page. It's a bad Web UI practice in general, but in those occasions that you must it's usually a requirement that can't be worked around. Hopefully this will be useful to you in those rare circumstances.&lt;/p&gt;&lt;div class='comment commentauthor' style='border: none 0px;min-height:30px;'&gt;&lt;small&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/WebLog/ShowPosts.aspx?Category=HTML'&gt;HTML&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%2f428973.aspx&amp;title=Forcing+Client+Windows+to+pop+up+as+Windows+in+Tabbed+Browsers"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f428973.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;/div&gt;&lt;p&gt;&lt;a href='/WebLog/wwBanner.ashx?a=c&amp;id=9492784c&amp;t=633525919370072500' target='_top'&gt;&lt;img src='http://www.west-wind.com/banners/WestwindWebStore.gif' border='0'&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RickStrahl?a=gkpZW7"&gt;&lt;img src="http://feeds.feedburner.com/~a/RickStrahl?i=gkpZW7" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=Hfo6UJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=Hfo6UJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=7H1sPj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=7H1sPj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=XhTzNJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=XhTzNJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=yDHM1j"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=yDHM1j" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=s35JzJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=s35JzJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=8yrUvj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=8yrUvj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/342859884" height="1" width="1"/&gt;</description>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=RickStrahl&amp;itemurl=http%3A%2F%2Fwest-wind.com%2Fweblog%2Fposts%2F428973.aspx</feedburner:awareness><feedburner:origLink>http://west-wind.com/weblog/posts/428973.aspx</feedburner:origLink></item>
    <item>
      <title>DevMaven Ads on the Web Log</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/341324378/426802.aspx</link>
      <guid isPermaLink="false">426802_200807210856</guid>
      <pubDate>Mon, 21 Jul 2008 08:56:13 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/426802.aspx#Comments</comments>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=426802</wfw:commentRss>
      <category>ISV</category>
      <category>Personal</category>
      <description>&lt;p&gt;If you've been visiting here for a while, you may have noticed that the advertising on this Web log has been cut down quite a bit recently. At the beginning of the month I decided to switch off from the mish mash of advertising that I was running previously, which included Google Adsense, Steve Smith's &lt;a href="http://theloungenet.com/Home" target="_blank"&gt;Lake Quincy Network&lt;/a&gt;, &lt;a href="http://theloungenet.com/Home" target="_blank"&gt;James Avery's The Lounge Network&lt;/a&gt; network and some of my own ads. Advertising here has brought in a small amount of side income that has roughly covered the hosting of the site and a little bit extra. While it's not been a lot of money it's always been enough to make me teeter on the side of the $ signs to put the ads&amp;nbsp; onto the site, but it required the mish mash to provide even this small stream of revenue . At the same time the amount taken in seemed small in comparison to the amount of content that is actually provided here - it's hard to gauge the worth of ad space of course, but I was actually considering turning off advertising altogether at some point because of the whole disproportion between ad payout and what the Ad services charge advertisers and what gets paid back to publishers (especially Google and Adsense which is an abomination - Google is getting rich of both advertisers and publishers because of it).&lt;/p&gt; &lt;p&gt;So a couple of months ago I started talking with &lt;a href="http://stevesmithblog.com/" target="_blank"&gt;Steve Smith&lt;/a&gt; about advertising and some of the pain points for publishers and advertisers alike and started throwing some ideas around about a few different approaches to serving ads. Steve's really the guy with the ideas, but there was a bit of back and forth and I liked what I was hearing. I've been frustrated with the advertising publishing I've been doing for a variety of reasons and was in fact thinking of just dropping the whole thing. However after talking with Steve a bit I decided to see what he'd come up with. &lt;/p&gt; &lt;p&gt;The end result is what now has become &lt;a href="http://devmavens.com/" target="_blank"&gt;DevMavens&lt;/a&gt; which is a highly focused and somewhat exclusive advertising arrangement that serves ads to only a few member sites that are part of the DevMavens network and includes only a small number of advertisers at any given month. The concept of this type of specialized network isn't new (in fact, The Lounge used a similar model), but what is different for me at least is that the payback for the publishers is a bit larger than the typical CPM network. For me, the payment arrangements result in a significantly higher payback for running ads and as a bonus it requires only a single, relatively small ad on each page of the Web log. &lt;/p&gt; &lt;p&gt;I hope you'll agree that this single ad format is much less distracting than the 6 or so ads that were running previously on all the pages here, so hopefully this won't be just a boon for me but also for those of you who kindly come to visit this Web log frequently and actually click through into the site either from the RSS feed or from search results. I'm also glad to be working with Steve, who's been great to work with in the past for ad tuning and pinging on advertising issues in general, as well as just being a good developer friend I talk to from time to time about dev issues anyway.&lt;/p&gt; &lt;h3&gt;Love Hate Relationship with Ads&lt;/h3&gt; &lt;p&gt;Advertising for me is a love/hate issue and it's ironic&amp;nbsp; because I tend to think of advertising as &lt;a href="http://www.west-wind.com/WebLog/posts/302826.aspx" target="_blank"&gt;the root of a lot of problems on the Web&lt;/a&gt;. So in a way it's a bit hypocritical to whore space on this site to advertising. But yet the lure of some &lt;em&gt;recurring&lt;/em&gt; side income is always very enticing. The reality is that a lot of effort has gone into the nearly 1000 posts that have made it into the Web log and there's a certain amount of profit potential there even as the content keeps growing. It seems a waste to throw that away and the income is maybe an added incentive to keep at it, especially on those stretches when writer's block or very busy schedules seem to get in the way.&lt;/p&gt; &lt;p&gt;There's no telling whether the DevMavens campaign will continue to pan out, but for the moment this definitely is a big improvement on all fronts as it simplifies things, makes for a cleaner layout and doesn't hurt the bottom line. Woot.&lt;/p&gt;&lt;div class='comment commentauthor' style='border: none 0px;min-height:30px;'&gt;&lt;small&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/WebLog/ShowPosts.aspx?Category=ISV'&gt;ISV&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/WebLog/ShowPosts.aspx?Category=Personal'&gt;Personal&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%2f426802.aspx&amp;title=DevMaven+Ads+on+the+Web+Log"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f426802.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;/div&gt;&lt;p&gt;&lt;a href='/WebLog/wwBanner.ashx?a=c&amp;id=e47b9595&amp;t=633525919370072500' target='_top'&gt;&lt;img src='http://www.west-wind.com/banners/wwstore_small.gif' border='0'&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RickStrahl?a=wtIkeQ"&gt;&lt;img src="http://feeds.feedburner.com/~a/RickStrahl?i=wtIkeQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=2BpPLJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=2BpPLJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=wD7Mtj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=wD7Mtj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=ARP4vJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=ARP4vJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=iEIihj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=iEIihj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=4eFHRJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=4eFHRJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=4Rfiwj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=4Rfiwj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/341324378" height="1" width="1"/&gt;</description>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=RickStrahl&amp;itemurl=http%3A%2F%2Fwest-wind.com%2Fweblog%2Fposts%2F426802.aspx</feedburner:awareness><feedburner:origLink>http://west-wind.com/weblog/posts/426802.aspx</feedburner:origLink></item>
    <item>
      <title>Buying a new Server</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/340140877/425906.aspx</link>
      <guid isPermaLink="false">425906_200807192107</guid>
      <pubDate>Sat, 19 Jul 2008 21:07:10 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/425906.aspx#Comments</comments>
      <slash:comments>26</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=425906</wfw:commentRss>
      <description>&lt;p&gt;It's time to retire my existing Web Server which is going on 7 years now. The box that this site is running on currently is an old style 2ghz Pentium 4 box with 1 gig of memory and it's starting to creak at the edges pretty hard with a few off and on failures to power and the system board components (lthe clock seized to work a few weeks ago). As of late the box has been locking up on a few occasions - and in fact just as I started writing this post today it just locked up again. Thankfully the lockups are not hardware fatal and the machine keeps on ticking after being rebooted by the ISP staff, but clearly this box is reaching the end of its hardware life cycle and usefulness.&lt;/p&gt; &lt;p&gt;I've been meaning to upgrade the box for a while, but frankly there's really not been a compelling reason to do so until recently. Even with the fairly large and various amount of stuff running on this server including the WebLog, our message board, a large variety of sample applications, my &lt;a href="http://www.west-wind.com/westwindwebstore/" target="WebStore"&gt;West Wind Web Store&lt;/a&gt; (in various different versions actually &amp;lt;s&amp;gt;) and a bunch of smaller internal applications, it never seizes to amaze me that this underpowered box does as well as it does. The other reason I'd been holding out as long as I had has been waiting for Server 2008. I wanted to wait for the new OS to update to save myself from an update in the future and having more synchronicity between Vista on the desktop and the 2008 server on live site.&lt;/p&gt; &lt;p&gt;Anyway, it's time to get a new box and I'm kind of torn between the choices on what to get. The last box was a home built box that cost me somewhere around $500 to build at the time. It was an emergency replacement box swapped in for a slowly failing server at the time and it just somehow worked out as the permanent replacement. I'd say for the years of services it's done that was a good price to value effort. The old box was basically a desktop box that my ISP at Gorge Net in Hood River has been kind enough to co-locate for me.&lt;/p&gt; &lt;p&gt;The question now is though what to get for a new box. I've been leaning towards just building another box with an Intel Core Quad processor and a gobs of memory, plus some high performance drives for best performance, but things have changed with processor designs significantly over the last few years with chips running super hot. So I'm seriously wondering whether a desktop processor is a good idea for an always-on server environment. Additionally I'm really pressed for time as I have a two week window to get the components, build the box, run a burn in and then move everything from the old server onto the new box while I'm actually in Hood River with physical access to the box. Finally, I'm not all that keen on building my own boxes anymore especially in regards to getting those monster processors installed and properly set up for cooling and optimal tuning. My last home brew installation of an internal office server took me way longer than I care to admit to get the machine into stable operation and while that kind of experimentation was fine for a desktop box I can fuck with anytime, I don't have that privilige with a server at a (somewhat) remote location.&lt;/p&gt; &lt;p&gt;So, I guess I'm asking for a some experienced advice amongst you, my dear readers. &lt;/p&gt; &lt;p&gt;Some of the choices I've been toying with are:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Build my own&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If I build my own box the price is probably the lowest and I get exactly what I want, but as I mentioned above I am a little worried about component overheating and life time. Pricing for what I'm looking at looks to be around $600 or so for a Intel Core Quad with 4gig and two SATA drives plus a new box and a beefy power supply. The price is right but I'm not sure if this is still a good idea. &lt;/p&gt; &lt;p&gt;Another option is to buy a bare bones, pre-installed system that has Box and CPU mounted and ready to go. But in briefly looking around I didn't find a lot of choice in this space from most of the component vendors, so this is probably not an option. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Get a Desktop Box from Dell or some other Vendor&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Pricing a box that has similar components (minus extra drive and maybe additional memory) from Dell costs roughly the same, but there's less control over the components. It's amazing how cheap boxes have become. Effectively the pricing doesn't seem too much more than home build but I'd probably have to do some component swapping to get the high end drive and memory upgrades still. The advantage for me though is that I don't have to wait for components to show up and build the box and hopefully get a reasonably tuned box that I can just install the OS on and be done with.&lt;/p&gt; &lt;p&gt;Here's with what I came up with at Dell:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;img alt="" src="https://si.cdn.dell.com/images/global/general/spacer.gif" width="1" border="0" height="1"&gt;&lt;br&gt;Dell Inspiron 530&lt;br&gt;Intel Core 2 Quad Processor Q6600 (8MB L2 cache,2.4GHz,1066FSB), Genuine Windows Vista® Home Premium Service Pack 1&lt;br&gt;Unit Price&lt;br&gt;$728.00&lt;br&gt;&lt;br&gt;Genuine Windows Vista® Home Premium Service Pack 1 (will be dumped) &lt;/p&gt;&lt;p&gt;Memory&lt;br&gt;4GB Dual Channel DDR2 SDRAM at 800MHz- 4DIMMs  &lt;/p&gt;&lt;p&gt;Keyboard and Mouse Bundles&lt;br&gt;Dell USB Keyboard and Dell Optical USB Mouse  &lt;/p&gt;&lt;p&gt;Monitor&lt;br&gt;No Monitor  &lt;/p&gt;&lt;p&gt;Video Cards&lt;br&gt;ATI Radeon HD3650 256MB  &lt;/p&gt;&lt;p&gt;Hard Drives&lt;br&gt;500GB Serial ATA Hard Drive (7200RPM) w/DataBurst Cache™  &lt;/p&gt;&lt;p&gt;Floppy Drive and Media Reader&lt;br&gt;3.5in Floppy Drive  &lt;/p&gt;&lt;p&gt;Mouse&lt;br&gt;Mouse included with Keyboard purchase  &lt;/p&gt;&lt;p&gt;Network Interface&lt;br&gt;Integrated 10/100 Ethernet  &lt;/p&gt;&lt;p&gt;Optical Drive&lt;br&gt;16X DVD+/-RW Drive  &lt;/p&gt;&lt;p&gt;Sound Cards&lt;br&gt;Integrated 7.1 Channel Audio  &lt;/p&gt;&lt;p&gt;Warranty &amp;amp; Service&lt;br&gt;1Yr In-Home Service, Parts + Labor, 24x7 Phone Support  &lt;/p&gt;&lt;p&gt;Sub total:$728.00&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Looking over prices what it would cost me to build a box with similar components it's not going to be any cheaper, even if I end up replacing the drive with something faster later on. &amp;lt;shrug&amp;gt;  &lt;/p&gt;&lt;p&gt;The question again is just how much can you trust a desktop box (especially from Dell and Inspiron) to last in a server environment today? I've had good luck with non-server boxes in the past with all of them lasting close to 5 years before they got obsolete.&amp;nbsp; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Get a Server Box from Dell or some other Vendor&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While at Dell I also checked out the servers and prices there also seem reasonably decent for a mid range non-rack server. For a quad core 2.5ghz Xeon with a similar configuration (plus 2 drives unfortunately) I'd end up with something like this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;img alt="" src="http://i.dell.com/images/global/general/spacer.gif" width="1" border="0" height="10"&gt;&lt;img alt="" src="http://i.dell.com/images/global/general/spacer.gif" width="1" border="0" height="1"&gt;&lt;br&gt;PowerEdge T300&lt;br&gt;Quad Core Intel® Xeon® X3323, 2.5GHz, 2x3M Cache, 1333MHz FSB, No Operating System&lt;br&gt;$1,666.00&amp;nbsp;&amp;nbsp; Save $688 on select PowerEdge™ T300 servers through Dell Small Business.  &lt;/p&gt;&lt;p&gt;Memory&lt;br&gt;4GB DDR2, 667MHz, 2x2GB Dual Ranked DIMMs  &lt;/p&gt;&lt;p&gt;Primary Hard Drive&lt;br&gt;250GB 7.2k RPM Serial ATA 3Gbps 3.5-in Cabled Hard Drive  &lt;/p&gt;&lt;p&gt;2nd Hard Drive&lt;br&gt;250GB 7.2k RPM Serial ATA 3Gbps 3.5-in Cabled Hard Drive  &lt;/p&gt;&lt;p&gt;Hard Drive Configuration&lt;br&gt;Onboard SATA, 1-4 Drives connected to Onboard SATA Controller - No RAID&lt;/p&gt; &lt;p&gt;Floppy Drive&lt;br&gt;No Floppy Drive  &lt;/p&gt;&lt;p&gt;Network Adapter&lt;br&gt;On-Board Dual Gigabit Network Adapter  &lt;/p&gt;&lt;p&gt;CD/DVD Drive&lt;br&gt;16x DVD-ROM Drive, Internal, SATA  &lt;/p&gt;&lt;p&gt;System Documentation&lt;br&gt;Electronic Documentation and OpenManage CD Kit  &lt;/p&gt;&lt;p&gt;Chassis Configuration&lt;br&gt;Chassis with Cabled Hard Drive and Non-Redundant Power Supply  &lt;/p&gt;&lt;p&gt;Hardware Support Services&lt;br&gt;3Yr Basic Hardware Warranty Repair: 5x10 HW-Only, 5x10 NBD Onsite  &lt;/p&gt;&lt;p&gt;Power Cords&lt;br&gt;Power Cord, NEMA 5-15P to C13, wall plug, 10 feet  &lt;/p&gt;&lt;p&gt;TOTAL:$978.00&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;which seems reasonable for a server. Components as a whole seem a little less powered than the desktop counterparts, but I suspect the Xeon processors are better optimized for server operation and heat dispersion for running in always on scenarios.&lt;/p&gt; &lt;p&gt;Unfortunately in various configurations I haven't been able to get exactly the config I'd like to see so I probably have to call Dell to fine tune a little bit if possible or at least ditch the third drive for a 10k boot drive.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Looking for Feedback&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The environment will be almost purely for hosting my own Web applications, mostly ASP.NET applications running SQL Server as a data backend all local in this case plus a few older COM based Web applications. There are obviously more expensive solutions available especially in rack mount form but I'm incined to think that most of the server boxes are just badly overpriced for what performance they provide. Am I totally off my nut on that or does that seem reasonable at all?&lt;/p&gt; &lt;p&gt;I thought I'd take advantage of the vast pool of folks out there and I would love to&amp;nbsp; hear some thoughts on what's worked for you in small shop server installs focused purely on Web Servicing for small to medium level Web load. &lt;/p&gt;&lt;div class='comment commentauthor' style='border: none 0px;min-height:30px;'&gt;&lt;small&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%2f425906.aspx&amp;title=Buying+a+new+Server"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f425906.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RickStrahl?a=17N5hj"&gt;&lt;img src="http://feeds.feedburner.com/~a/RickStrahl?i=17N5hj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=1ZqZrJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=1ZqZrJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=rLAd8j"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=rLAd8j" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=8u4QSJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=8u4QSJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=99N2Aj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=99N2Aj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=yOsSjJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=yOsSjJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=o8Llmj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=o8Llmj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/340140877" height="1" width="1"/&gt;</description>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=RickStrahl&amp;itemurl=http%3A%2F%2Fwest-wind.com%2Fweblog%2Fposts%2F425906.aspx</feedburner:awareness><feedburner:origLink>http://west-wind.com/weblog/posts/425906.aspx</feedburner:origLink></item>
    <item>
      <title>West Wind Ajax Toolkit updated</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/336390437/422295.aspx</link>
      <guid isPermaLink="false">422295_200807151946</guid>
      <pubDate>Tue, 15 Jul 2008 19:46:32 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/422295.aspx#Comments</comments>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=422295</wfw:commentRss>
      <category>AJAX</category>
      <category>ASP.NET</category>
      <description>&lt;p&gt;I've finally had some time to update the West Wind Ajax Toolkit to version 1.90. A number of these changes I've written about and have updated previously, but this update finalizes a number of these updates into a full release. There are a number of enhancements to the existing functionality as well as a few new helper components that I'm finding very useful these days.&lt;/p&gt; &lt;p&gt;As always you can grab the latest version from:&lt;br&gt;&lt;a href="http://www.west-wind.com/tools/wwHoverPanel/" target="_blank"&gt;West Wind Ajax Toolkit page&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The toolkit consists of a number of controls to provide JSON callbacks and JSON service, popup hover windows, modal dialogs and a few other Ajax based controls. In addition the Toolkit includes a host of utility classes that provide services to ASP.NET AJAX pages including a generic JSON service, a Json Serializer, a ClientScriptProxy that can automatically route to either ClientScript or the ASP.NET ScriptManager, a ScriptVariables class that lets you embed data into client pages easily for client code access, a ScriptContainer for adding scripts to a page consistently in markup and through code, a script minifier and a JavaScript GZIP compression tool and much more.&lt;/p&gt; &lt;p&gt;Following are a few of the highlights of the release's new and changed components.&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;Improved JsonSerializer&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;Thanks to the help from Joe McLain there have been a number of improvements in the serialization code of the parser. It now deals much better with array/list de-serialization which previously was a bit shaky. Arrays/Lists are now supported as root objects or as embedded properties in objects. The latter worked before but there were problems with root arrays. A number of string formatting issues in deserialization are also fixed and the date parsing logic can now deal with ASP.NET AJAX/WCF style JSON dates, as well as the proposed ISO date literal and plain old new Date() syntax. Internally the serializer uses the ASP.NET AJAX date format now, but there's a switch which allows generating the new Date() 'code' syntax instead so you can use the serializer for creating fully runnable JavaScript.&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;ScriptVariables class&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;&lt;a href="http://www.west-wind.com/weblog/posts/259442.aspx" target="_blank"&gt;I talked about this class some time ago&lt;/a&gt; - it provides the ability to easily embed server variables into client side code by way of a client side object that contains these variables. So you get ServerVars.MyVariable with a server set value applied. Values can be applied literally via Add methods or be applied dynamically which reads values out of any object reference or control property. &lt;/p&gt; &lt;p&gt;Values are properly JSON encoded and can then easily be accessed on the client. The object also supports the ability to read these object values - optionally - back on the server side in a Postback if they are changed on the client. This is a great way to persist values without explicitly having to assign them to hidden variables or a field on the form.&lt;/p&gt; &lt;p&gt;You can create multiple server script variable objects as long as they each output a unique name (with the default being ServerVars) and control builders can also use this tool from within control code without interference with application level code by using a unique name.&lt;/p&gt; &lt;p&gt;Optionally this control can also optionally generate properties for each of the controls on a form and provide non-NamingContainer Ids. So even if txtName is inside of a user control you can access ServerVars.txtNameId to get the control name.&lt;/p&gt; &lt;p&gt;I've found this component to be extremely useful as it provides an easy way to embed:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Variable names that are mangled by ASP.NET naming containers - no more &amp;lt;%= txtName.ClientID %&amp;gt;&lt;br&gt;either explicitly added or automatically generated through AddClientIds()&lt;/li&gt; &lt;li&gt;Pushing down initially loaded data for JavaScript to consume (including complex types)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I've found this class extremely useful in Ajax applications, especially for pushing down sensible control names and avoiding the &amp;lt;%= ClientID %&amp;gt;mess on the client.&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;ScriptContainer Class&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;I've mentioned this class in several posts - it's essentially a script manager that's somewhat similar to the ASP.NET ScriptManager, except it doesn't rely on .NET 3.5 and doesn't output MS Ajax scritps by default. It also provides a bit more control with the ability to determine where scripts are rendered: In the header, after the form tag (standard ASP.NET mode) or inline where the control sits. This setting can be applied either to the control in general or to the individual scripts added, which allows you a little more control over how scripts get loaded.&lt;/p&gt; &lt;p&gt;Scripts can be added either in markup or programmatically and there's only a single instance on a page that's allowed so all scripts can be added to the same manager. This means controls, page code and markup can ensure that scripts only get added once. The syntax uses HTML generic controls using &amp;lt;script&amp;gt; tags so there's Intellisense support for the embedded scripts.&lt;/p&gt; &lt;p&gt;Additionally you can specify whether you want to allow min script to be accessed (ie. .min.js files that are compressed or minimized). If you do and the file exists the control will use the minimized files when running the site in non-debug mode.&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;JavaScriptMinifier.MinfyDirectory Method&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;This new method can be used to minify all java script files in a directory or directory hierarchy in batch to create min script files. You specify the path the min extension and whether to recurse into child paths and this method will create the min files automatically checking for changes as needed. This works great in combination with the ScriptContainer class by sticking a call to this static function into Application_Start which will check for script changes on startup of the App.&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;A few JavaScript Helper classes for Formatting&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;This update also includes a number of simple helper functions for string, number and date formatting. String gets a basic but highly useful .format() function that uses simple C# string replacement (but without format options). Number gets a .numberFormat() function that does decimal and currency style formatting (c,n,f3,n2) and Date gets formatDate that provides basic formatting using the .NET date format specifiers ( ie.&amp;nbsp; MM dd yyyy, HH mmy). This is nothing new, but it's just so damn useful and necessary that it has to be in the utility library.&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;Additional changes&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;There are many more small changes and updates especially in the JavaScript library that fix a number of small issues that have been reported and you can find out what's updated here:&lt;/p&gt; &lt;p&gt;&lt;a href="http://west-wind.com/tools/wwHoverPanel/docs/index.htm?page=_1S606OAGO.htm" target="_blank"&gt;What's new in West Wind Ajax Toolkit 1.90&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;Interested in Feedback&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;As always I'm interested in feedback on the components and how you might be using them. There's a lot of functionality in this toolkit, yet I suspect a lot of people are taking components out of it and using individual pieces in their own libraries or applications, which is great.&lt;/p&gt; &lt;p&gt;I'm especially interested though in feedback about the new ScriptContainer and ScriptVariables classes as I think they are great generic tools that could be expanded upon a bit more. Feedback can drive this better so if you have any comments post them here or on the &lt;a href="http://www.west-wind.com/wwThreads/default.asp?forum=West Wind Web Tools for .NET" target="_blank"&gt;support forum&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;What's Next?&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;A couple of things really should happen next. First of all the samples of the toolkit are getting reaaaallly long in the tooth. While they work and get the point across, most look crappy and use some rather lame examples. So the samples will be updated at some point shortly.&lt;/p&gt; &lt;p&gt;For the next major version there will be a complete reworking of the client library to use jQuery. There's a ton of overlap between wwScriptLibrary.js and what jQuery provides and using jQuery to provide the base and core library would reduce the code in wwScriptLibrary by more than half. jQuery doesn't provide all the utility functionality provided in wwScriptLibrary but there's definitely some overlap. I think most of the higher level components - especially the client side control interfaces - can easily be maintained backwards compatible or with only minor changes even given this major of an update. This will be a major change but it's looking good for keeping the interface intact and not breaking old code. Once this is done it'll be much easier to start integrating more jQyery based components in a similar fashion as the wwDatePicker.&lt;/p&gt; &lt;p&gt;Anyway, if you have any thoughts on any of this please leave a note here or &lt;a href="http://www.west-wind.com/wwThreads/default.asp?forum=West Wind Web Tools for .NET" target="_blank"&gt;on the message board&lt;/a&gt;.&lt;/p&gt;&lt;div class='comment commentauthor' style='border: none 0px;min-height:30px;'&gt;&lt;small&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/WebLog/ShowPosts.aspx?Category=AJAX'&gt;AJAX&lt;/a&gt;&amp;nbsp;&amp;nbsp;&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%2f422295.aspx&amp;title=West+Wind+Ajax+Toolkit+updated"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f422295.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RickStrahl?a=sRqNLJ"&gt;&lt;img src="http://feeds.feedburner.com/~a/RickStrahl?i=sRqNLJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=gJDzhJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=gJDzhJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=jzYa4j"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=jzYa4j" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=WitaMJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=WitaMJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=GYH7Uj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=GYH7Uj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=9mVm1J"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=9mVm1J" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=z5tjlj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=z5tjlj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/336390437" height="1" width="1"/&gt;</description>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=RickStrahl&amp;itemurl=http%3A%2F%2Fwest-wind.com%2Fweblog%2Fposts%2F422295.aspx</feedburner:awareness><feedburner:origLink>http://west-wind.com/weblog/posts/422295.aspx</feedburner:origLink></item>
    <item>
      <title>Static Singletons for ASP.NET Controls</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/332420576/417588.aspx</link>
      <guid isPermaLink="false">417588_200807110719</guid>
      <pubDate>Fri, 11 Jul 2008 07:19:14 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/417588.aspx#Comments</comments>
      <slash:comments>7</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=417588</wfw:commentRss>
      <category>ASP.NET</category>
      <category>CSharp</category>
      <description>&lt;p&gt;When building generic ASP.NET Server controls that also provide a sort of API service to other custom controls or page level code, it's often necessary to ensure that only a single instance of a control exists, and that only that single instance of this control or component can be accessed in the context of an ASP.NET request. While this is usually easy to accomplish in actual page code (since you can reference the control or component explicitly), if the API is also consumed by other Server Controls it's crucial that it's easy and efficient to find and access that single instance of a control effectively. This isn't a typical scenario, but it's a common pattern for controls that expose API level functionality in addition to the actual control based markup. &lt;/p&gt; &lt;p&gt;This isn't a new concept &lt;a href="http://dotnetslackers.com/Community/blogs/simoneb/archive/2006/08/21/The-ASP.NET-Singleton_2D00_per_2D00_Request-pattern.aspx"&gt;(Simone had a great post&lt;/a&gt; on this some time ago), but I've run into this pattern so many times and have also gotten a number of questions about this that I thought I'd revisit it here since I just went through the excercise again.&lt;/p&gt; &lt;p&gt;For example, a few days ago I talked about a &lt;a href="http://www.west-wind.com/weblog/posts/413878.aspx"&gt;ScriptContainer control&lt;/a&gt; that's akin to the ASP.NET ScriptManager control, but with a few additional features. The idea is that there's a single level API that can be used to retrieve an instance to the ScriptContainer, so that code either in CodeBehind or a customer Server Control has access to that instance sitting on a page. &lt;/p&gt; &lt;p&gt;So, in this example I can reference the wwScriptControl on the page with code like this:&lt;/p&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: rgb(43,145,175)"&gt;wwScriptContainer&lt;/span&gt; script = &lt;span style="color: rgb(43,145,175)"&gt;wwScriptContainer&lt;/span&gt;.Current;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;script.AddScript(&lt;span style="color: rgb(163,21,21)"&gt;"~/scripts/wwEditable.js"&lt;/span&gt;, &lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;and always be guaranteed that I get that single instance of the control whether it's already embedded in the page markup or if not it's created on the fly and returned to me. Incidentally the ASP.NET ScriptManager also does something similar with its GetCurrent() method, but it only returns an instance if there's already one loaded - it's your responsibility to create one and add it to the page otherwise. The wwScriptContainer.Current property here instead always returns a control instance including creating one and adding it to the page when none exists yet.&lt;/p&gt;
&lt;p&gt;Another example, where this applies is my &lt;a href="http://west-wind.com/weblog/posts/10246.aspx"&gt;ClientScriptProxy API&lt;/a&gt;, which returns a single instance of the ClientScriptProxy object that references either a ScriptManager if one is on the page, or otherwise talks to the Page.ClientScript object and so provides the same behavior regardless of which API is available. In this case too I need to ensure that only a single instance of this object exists and that I can always retrieve that single instance from anywhere in code. The ClientScript.Current property serves exactly this purpose. &lt;/p&gt;
&lt;h3&gt;ASP.NET Singletons and HttpContext.Current&lt;/h3&gt;
&lt;p&gt;This &lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern"&gt;Singleton pattern&lt;/a&gt; can be applied to any ASP.NET control (or even component or Page) that in addition to a markup based control interface also exposes a generic API that scoped to the current ASP.NET request/page executing. In ASP.NET request level state is managed through the HttpContext object which is yet another example of a Singleton. &lt;/p&gt;
&lt;p&gt;The basic concept of a Singleton is very straight forward. Here's Simone's example which is as concise as it gets:&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SingletonPerRequest&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SingletonPerRequest&lt;/span&gt; Current&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current.Items[&lt;span style="color: rgb(163,21,21)"&gt;"SingletonPerRequest"&lt;/span&gt;] ??&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current.Items[&lt;span style="color: rgb(163,21,21)"&gt;"SingletonPerRequest"&lt;/span&gt;] =&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SingletonPerRequest&lt;/span&gt;())) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SingletonPerRequest&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;where the SingletonPerRequest() creates whatever object reference you need to create. The key thing is that the property is static and that it returns a value that is stored on the HttpContext.Items collection.&lt;/p&gt;
&lt;p&gt;To understand how this works it's important to understand how the HttpContext object relates to the ASP.NET request flow. HttpContext.Current represents the current ASP.NET Request context and this context is available throughout the course of an ASP.NET request starting with the HttpApplication.BeginRequest pipeline event all the way through HttpApplication.EndRequest(). It also includes module and handler execution which is also part of the application pipeline.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.west-wind.com/presentations/howaspnetworks/Figure%207.png"&gt;&lt;/p&gt;
&lt;p&gt;ne important aspect of the HttpContext object is that it also contains an Items collection - an in-process statebag that allows you to attach arbitrary state at any point in processing of a request and access it later. Because HttpContext.Current is static and always accessible any state stored in Items is always available (unless explicitly released) until the end of the request. It's an ideal store for request specific information like for example store an instance reference to a control that should only be accessed through a single reference. IOW, a Singleton.&lt;/p&gt;
&lt;p&gt;Long story short for my ScriptContainer example, I can use HttpContext.Current.Items["wwScriptContainer"] to save and instance of the script container control and then implement a custom method or property like .Current to retrieve that single instance.&lt;/p&gt;
&lt;p&gt;Here's what this code looks like for ScriptContainer:&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; ScriptContainer()&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;{&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;._Scripts = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;HtmlGenericControl&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;this&lt;/span&gt;._InternalScripts = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ScriptItem&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// *** Save a Per Request instance in Context.Items so we can retrieve it&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp; generically from code with wwScriptContainer.Current&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current.Items.Contains(&lt;span style="color: rgb(163,21,21)"&gt;"ScriptContainer"&lt;/span&gt;))&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"Only one wwScriptContainer is allowed per page."&lt;/span&gt;);&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current.Items[&lt;span style="color: rgb(163,21,21)"&gt;"ScriptContainer"&lt;/span&gt;] = &lt;span style="color: blue"&gt;this&lt;/span&gt;;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt; }&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;override&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Dispose()&lt;/pre&gt;&lt;pre style="margin: 0px"&gt; {&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current.Items.Remove(&lt;span style="color: rgb(163,21,21)"&gt;"ScriptContainer"&lt;/span&gt;);&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt; }&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; Returns a current instance of this control if an instance&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; is already loaded on the page. Otherwise a new instance is&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; created, added to the Form and returned.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; It's important this function is not called too early in the&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; page cycle - it should not be called before Page.OnInit().&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; This property is the preferred way to get a reference to a&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; wwScriptContainer control that is either already on a page&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; or needs to be created. Controls in particular should always&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; use this property.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: gray"&gt;///&lt;/span&gt;&lt;span style="color: green"&gt; &lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ScriptContainer&lt;/span&gt; Current&lt;/pre&gt;&lt;pre style="margin: 0px"&gt; {&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;get&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt; &lt;span style="color: green"&gt;// *** We need a context for this to work!&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43,145,175)"&gt;ScriptContainer&lt;/span&gt; ctl = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// *** Retrieve the current instance&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctl = &lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current.Items[&lt;span style="color: rgb(163,21,21)"&gt;"ScriptContainer"&lt;/span&gt;] &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ScriptContainer&lt;/span&gt;;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (ctl != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; ctl;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctl = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ScriptContainer&lt;/span&gt;();&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43,145,175)"&gt;Page&lt;/span&gt; page = &lt;span style="color: rgb(43,145,175)"&gt;HttpContext&lt;/span&gt;.Current.Handler &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Page&lt;/span&gt;;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (page == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;throw&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"ScriptContainer.Current only works with Page based handlers."&lt;/span&gt;); &lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; page.Form.Controls.Add(ctl);&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; ctl;&lt;/strong&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="margin: 0px"&gt; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The idea is that during initialization of the control the control/component is immediately pushed into a Context.Items item and saved. This instance becomes that single instance accessed. In fact, the constructor explicitly checks for multiple instances and throws if more than one is instantiated explicitly. This means you couldn't have multiple markup controls on the page or a markup control and manually create an instance.&lt;/p&gt;
&lt;p&gt;Once stored the Item stored reference - if one exists - can then be retrieved in the .Current property getter which checks to see if the item exists and returns it. &lt;/p&gt;
&lt;p&gt;Typically the .Current getter is also responsible for creating a new instance if one doesn't exist, but how that's accomplished or whether this is supported can vary wildly especially with controls. Here the code creates a generic instance and adds it to the ASP.NET form's Controls collection. Note that from within a static property you won't have access to the Page instance (ie. no this.Page) so you have to access the Page through the HttpContext.Current.Handler and cast that to a Page object.&lt;/p&gt;
&lt;p&gt;But again how that works will depend on your specific scenario. The issue is that if you have a control there may be a number of configuration settings that must be set in order to create an instance 'generically'. In the case of the ScriptContainer a generic version is acceptable, but with other controls configuration may be required. You may also need to know whether the control was returned from an existing instance or whether a new instance was created and so you might have an additional property that returns this fact. Or you can return &lt;em&gt;null&lt;/em&gt; from .Current and then explicitly let client code create the new instance and configure it. &lt;/p&gt;
&lt;p&gt;Typically Singletons have to worry about potential multi-user issues, but in ASP.NET request scenarios using HttpContext.Current this isn't an issue since the instance stored on .Current is visible only to the current request, which is of course running on a single thread. So multi-threading and locking is not something you have to worry about.&lt;/p&gt;
&lt;p&gt;This Singleton like approach is a pattern I use a lot for ASP.NET Controls that I create - it's a very useful tool for caching expensive construction and ensuring that you truly are only accessing a single instance of a control or component. But you can also apply this same sort of thing to Page level code or even request level code.&lt;/p&gt;
&lt;p&gt;If you want to take a closer look at the&amp;nbsp; ScriptContainer component you can find it as part of the &lt;a href="http://www.west-wind.com/tools/wwHoverPanel/"&gt;West Wind Ajax Toolkit download&lt;/a&gt;.&lt;/p&gt;&lt;div class='comment commentauthor' style='border: none 0px;min-height:30px;'&gt;&lt;small&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=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%2f417588.aspx&amp;title=Static+Singletons+for+ASP.NET+Controls"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f417588.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RickStrahl?a=i5Q8Yj"&gt;&lt;img src="http://feeds.feedburner.com/~a/RickStrahl?i=i5Q8Yj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=g9YboJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=g9YboJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=mg8odj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=mg8odj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=dMk7JJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=dMk7JJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=cIcDij"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=cIcDij" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=eCMGfJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=eCMGfJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=XeN3Ej"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=XeN3Ej" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/332420576" height="1" width="1"/&gt;</description>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=RickStrahl&amp;itemurl=http%3A%2F%2Fwest-wind.com%2Fweblog%2Fposts%2F417588.aspx</feedburner:awareness><feedburner:origLink>http://west-wind.com/weblog/posts/417588.aspx</feedburner:origLink></item>
    <item>
      <title>Inclusion of JavaScript Files</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/328787847/413878.aspx</link>
      <guid isPermaLink="false">413878_200807071105</guid>
      <pubDate>Mon, 07 Jul 2008 11:05:17 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/413878.aspx#Comments</comments>
      <slash:comments>25</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=413878</wfw:commentRss>
      <category>HTML</category>
      <category>JavaScript</category>
      <category>jQuery</category>
      <description>&lt;p&gt;I've been thinking a bit about JavaScript inclusion in the last few weeks as I've been working on quite a few different Web projects that use a fair bit of JavaScript functionality. One thing that I'm still trying to feel good about is how JavaScript is included into pages. There are a number of different ways that script embedding can be done especially with ASP.NET and none of them are really perfect.&lt;/p&gt; &lt;h3&gt;So what's the Problem?&lt;/h3&gt; &lt;p&gt;The issue is plain and simple, how do you deal with JavaScript inclusion into the page given that you have a fair number of JavaScript files that are bound to change frequently and across multiple projects/applications? My assumption here is that I'm using a few libraries and utility classes both public (jQuery and jQuery plug-ins mainly) and some internally developed support libraries. All in all many pages I deal with have typically 4 - 8 related JavaScript resources in AJAX centric applications with about 15-20 JavaScript resources overall involved in a typical project. In addition there are a few ASP.NET custom controls that depend on some of these&amp;nbsp; Ajax libraries and components.&lt;/p&gt; &lt;p&gt;My project load currently runs about 10 concurrent projects both internal and external and all of them are making use of these same script resources. Keeping versions of both my internal JavaScript libraries as well as external libraries in sync and up to date for each of these applications both in development and online gets to be challenging especially if the files are not necessarily delivered as a unified whole (ie. often I pick and choose which plug-ins to use).&lt;/p&gt; &lt;p&gt;So as you can probably see, it's pretty easy to be in 'script file hell' - I find myself using &lt;a href="http://www.scootersoftware.com/"&gt;Beyond Compare&lt;/a&gt; quite frequently to compare what's changed across different projects and update scripts precariously. I don't think there are easy solutions to this problem other than being very organized and managing versions as anally as possible but doing so can be a real drag on productivity as I move from project to project wondering if I have the correct current version.&lt;/p&gt; &lt;p&gt;There are many different ways that JavaScript resources can be loaded into pages from the basic manually managed header embedding of each script to using full ASP.NET resource management of all script files used. And plenty of other options in between. Try as I might I have not found a solution that really makes me feel all warm and fuzzy, so I'm curious what you are doing and what works best for you.&lt;/p&gt; &lt;p&gt;But let's review some of the approaches that are available to script embedding. For a specific example, let's take the more generic case of the &lt;a href="http://www.jquery.com/"&gt;jQuery library&lt;/a&gt;. Here are some of the options you have to get jQuery into your page:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Include in a scripts folder and link via script include as jQuery.js  &lt;li&gt;Include in a scripts folder and link via script include as jQuery-1.2.6.js (ie. version specific)  &lt;li&gt;Link to the version specific file at jQuery.com (typically jQuery-1.2.6.js)  &lt;li&gt;Link to the latest version at jQuery.com (ie. jQuery-latest.js)  &lt;li&gt;Link to some other script hosting site (ie. &lt;a href="http://code.google.com/apis/ajaxlibs/"&gt;Google's Ajax Lib API&lt;/a&gt;)&amp;nbsp; via script loading  &lt;li&gt;Embed scripts into ASP.NET Resources  &lt;li&gt;Use ScriptManager to load scripts either from Folder or Resources  &lt;li&gt;Use a custom script manager&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;All of these are options but they all have a few shortcomings as well.&lt;/p&gt; &lt;h3&gt;&lt;strong&gt;Local Script Files&lt;/strong&gt;&lt;/h3&gt; &lt;p&gt;The most common and easiest to understand approach is to simply embed local script links into the page. Add scripts into the header with &amp;lt;script src="scripts/jquery.js"&amp;gt; and off you go. In many situations this approach is perfectly fine, especially if script files are static and don't change frequently.&lt;/p&gt; &lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Configuration Settings&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;link&lt;/span&gt; &lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;="Standard.css"&lt;/span&gt; &lt;span style="color: red"&gt;rel&lt;/span&gt;&lt;span style="color: blue"&gt;="stylesheet"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/css"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt; &lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="scripts/jquery.js"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The issue with locally stored script files is that they they need to be updated if files changed. In a single application this is not a big issue. But if you're managing a large number of projects, changes to resusable scripts both of your or third party script libraries can easily become a burden and an exercise in version management. It'd be great if source control would solve this problem, but because resources are often mixed and matched storing a fixed set of script files under source control also doesn't really address this scenario either and wouldn't work very well anyway if the project is already under Source Control.&lt;/p&gt;
&lt;p&gt;In addition, if&amp;nbsp; you start using script code as part of related ASP.NET controls that might build on top of client script components&amp;nbsp; and that code has some dependencies on specific versions you can run into subtle versioning problems that are difficult to detect and test for. But even for relatively simple things like the static core jQuery library this can get sticky as new versions are frequently distributed. &lt;/p&gt;
&lt;p&gt;Versioning JavaScript files in general is a sticky issue. If you have local files, how do you version these JS resource? For example, many jQuery examples are shown using the version specific file like so:&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt; &lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="~/scripts/jquery-1.2.6.js"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This addresses versioning alright but then gets tedious when a new version gets released and all pages referencing this version needs to be updated. Again, with a single file this isn't terrible but now think about 10-20 resources used in an application that are all versioned this not really a good option. The other choice is to use a non-versioned file and just update the files - this is easier for updates but in turn can result in subtle feature incompatibilities if newer esions break old builds/dependencies.&lt;/p&gt;
&lt;p&gt;I personally lean towards the latter approach of using non-versioned filenames and take my chances hoping that changes are backwards compatible. In my own libraries even a breaking change is easily caught because I know what was changed intimately, but with third party libraries this can be tricky. For example, while using the jQuery.ui beta versions there many subtle breaking changes that were difficult to catch once the code was migrated to the release version because 95% of the code worked great. Testing JavaScript code consistently - especially UI code - is difficult at best and it's easy to have a subtle bug to not show up until the app is in production for a while.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;One Library Path for All Scripts&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Another option for 'local' script files might be to store all scripts in one place - say off the root of the Web site similar to the way ASP.NET 1.1 used to store resources in a /WebClient folder - and access them through this single script location. This solves the problem of having to copy versioned files around for each application and having a single store to update third party libraries and modify internal libraries. If there's a single store it's also easier to put the files under source control and manage them effectively.&lt;/p&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt; &lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="/scripts/jquery.js"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;But this approach also has a few problems. First it's not a generic solution because it requires that you use the same convention across applications. Might work fine for your own applications where you set policy, but if you're working to somebody else specs it may not be possible to dump scripts into a specific consistent location. &lt;/p&gt;
&lt;p&gt;It also may not necessarily be Ok to update scripts for every application at once, especially if scripts have breaking changes that might not work with older code not adapted to it. If you work with script files that are dependent on one another and these files are updated out of band it's easy to run into version problems. This is always a concern and not having local copies or linking to a single non-versioned script file is prone to potential version issues. Having local files in each app allows isolation from this version issue that can crop up with a single shared library folder. This issue is probably not a major concern &lt;/p&gt;
&lt;p&gt;I played around with this approach some time ago, but tossed the idea because of issues&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;External Hosting&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Another centralized approach is to use external hosting for certain script resources. This is more applicable for public librarires like jQuery, Prototype etc. and some high profile plug-ins available for them. External hosting also offloads the bandwidth for downloading scripts from your site to whatever public site hosting the scripts. Additionally, chances are that these script resources may be already cached in user browsers as the public resources are more widely used by users in general browsing which provides additional performance gains.&lt;/p&gt;
&lt;p&gt;For example, you can load the latest jQuery version from:&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt; &lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="http://www.jquery.com/src/jquery-latest.js"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;or a version specific one from the &lt;a href="http://code.google.com/p/jqueryjs/downloads/list"&gt;Google jQuery code repository&lt;/a&gt;:&lt;br&gt;&lt;br&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt; &lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;="http://jqueryjs.googlecode.com/files/jquery-1.2.6.js"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Most other major libraries also provide similar direct links to libraries so that you can offload loading from your site.&lt;/p&gt;
&lt;p&gt;Google recently also started hosting various JavaScript libraries with the &lt;a href="http://code.google.com/apis/ajaxlibs/"&gt;Google's Ajax Lib API&lt;/a&gt;. This API allows you to load script via JavaScript code in the page and allows&amp;nbsp; you to specify specific version numbers as part of the API call. This is&amp;nbsp; a clever way to get a better handle on versioning as you can potentially use single script file to in your app to load various script files with 'factory' function calls that load each library with the appropriate version. FWIW, it doesn't require Google's API to do this; you can take a similar approach by yourself by creating a small loader script that can be updated for each application (see below on how this can be done with jQuery for example).&lt;/p&gt;
&lt;p&gt;The disadvantage for external hosting is of course that you are dependent on an external provider to be up and running 100% of the time and to have adequate bandwidth to serve the script files.The provider can decide any time to remove files or APIs so at that point you may end up with bad links in your code. This is where an API - whether your own or Google's can actually buy some advantage because it can be changed in one place.&lt;/p&gt;
&lt;p&gt;Another concern is that scripts loaded across sites can also trigger warnings in the browser in some situations like SSL connections (to non SSL script resources) or strict browser requirements for cross domain loading of any files.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Dynamic Loading&lt;/strong&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;As mentioned above you can also load script dynamically from other script code. For example, it might be useful to load one script from another script to provide dependency loading. In jQuery for example you can do:&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: green"&gt;/// &amp;lt;reference path="jquery.js" /&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;$.getScript(&lt;span style="color: #a31515"&gt;"scripts/basepage.js"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;to pull in additional script code. &lt;/p&gt;
&lt;p&gt;One potential advantage of this approach is that you can build a simple loading api that turns scripts into resources with maybe some constants that determine which scripts to load and from where, consistently across an application. Rather than linking all scripts in pages you can call a single script file that handles loading all other scripts. &lt;/p&gt;
&lt;p&gt;However, when loading script dynamically&amp;nbsp; it's important to be very careful and ensure that the code in the dependency is not accessed before the script has actually loaded. This can have tricky side effects. In one app I was working on just today pages would call into&amp;nbsp; a loaded script function and it would work just fine the first time the page loaded or when a full refresh occurred, but not when the page was just reloaded via click (ie. most resources are already cached). The difference is that the other scripts are fully cached and so load time is significantly faster and the code executes before the second script page loads. In this case IE fails to see the function on page startup (even in $(document).ready() in jQuery) while FireFox, Opera and Safari properly delay the loading code.&lt;/p&gt;
&lt;p&gt;Most JavaScript libraries allow working around this via events fired when the script loading completes. In jQuery there's a handler that can be passed as a second parameter that's a handler:&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;$.getScript(&lt;span style="color: #a31515"&gt;"scripts/wwJquery.js"&lt;/span&gt;,&lt;span style="color: blue"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; showStatus(&lt;span style="color: #a31515"&gt;"Ready"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;});&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;which will reliably cause dependent code to run. But it's not always feasible to tie code to a specific library having been loaded. Often you have to wait on multiple libraries. Oddly I've seen a host of problems with this approach both with jQuery, the Google API while script loading from the page's &amp;lt;script&amp;gt; tags seems to work just fine. Detecting script completion across browsers is tricky especially in IE it appears.&lt;/p&gt;
&lt;p&gt;I have this approach on my list of things to play around with someday, but given the mixed results I've seen with load order failures I'm incline to pass this option up completely.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;ASP.NET Resources&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;When using ASP.NET it's also possible to rein in JavaScript resources by building them into ASP.NET compiled assemblies as Resources. Using this approach allows the resources to be stored in a single location that is centrally managed. Web Applications can then access these resources by calling &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.registerclientscriptinclude.aspx"&gt;Page.ClientScript.RegisterClientScriptInclude()&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.registerclientscriptresource.aspx"&gt;Page.ClientScript.RegisterClientScriptResource()&lt;/a&gt;&amp;nbsp; or the methods of the same name on the ASP.NET ScriptManager control.&lt;/p&gt;
&lt;p&gt;When using resources in a separate non-Web project, the project can be added other solutions and so can be shared across multiple projects which can both read the resources and modify any of them and have the changes reflected in any other application that includes the resource (or more often control ) assembly.&lt;/p&gt;
&lt;p&gt;I use ASP.NET resources a lot for a variety of purposes from images to scripts to css files and it's a great way to put everything into one place. But resources are not without their problems either. The worst issue by far is that they produce hideously long URLs that are non-transparent in the page and you can't easily tell what each script file points at. They also take up a fair bit of space (a typical WebResource.axd url can be 150 chars long). Additionally the API to actually load these script files is a code only API that needs to be handled in Codebehind of the page with no HTML page markup equivalent.&lt;/p&gt;
&lt;p&gt;Resources are a must if you're building controls that have script dependencies in my opinion and that's how I've been using them. I use my own script library that has both client and server components and the server controls need to ensure that scripts are loaded appropriately into the page. Without resources these controls would have to explicitly require the developer to add scripts to the page which would be a bit hokey. So the control internally loads the appropriate resources itself and in the right order and so ensures that the component is self contained.&lt;/p&gt;
&lt;p&gt;On the flip side using resources this way can be a problem if you also use the same library for other coding. The smaller problem is that it's very easy to double load resources when you forget that a component loads the resources internally. Further it's possible that the component loads the resources too late or in the wrong order from what the same page code might require if there are dependencies. &lt;/p&gt;
&lt;p&gt;In worse cases there may be issues where there are load order problems where the page control order rather than manual ordering end up determining the order in which scripts load. Again, this can become tricky if you have libraries that depend on each other like say a jQuery and a jQuery plug-in, or my personal library that might depend also on jQuery in certain parts. &lt;/p&gt;
&lt;p&gt;Resources also don't work well with Intellisense, except when using them with the ScriptManager control (see below). Otherwise the resource URLs aren't transparent so there's no easy way to embed scripts into other JavaScript resources as /// &amp;lt;script reference="" /&amp;gt;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The big problem is that ASP.NET natively doesn't have a native script loading API that works both for markup and code based script injection. Because the ClientScriptManager is a code only component it's very difficult to coordinate script loading both through markup and CodeBehind or component code and it can get very tricky to coordinate script dependencies loaded from resources if those same scripts also need to be loaded for other code.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;ASP.NET Script Manager&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Ah, but what about the new &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.aspx"&gt;ScriptManager&lt;/a&gt; control that's part of &lt;a href="http://www.asp.net/ajax/default.aspx?wwwaspnetrdirset=1"&gt;Microsoft ASP.NET AJAX&lt;/a&gt;? It addresses a number of the issues that I've mentioned above. Indeed, ScriptManager provides a mirror interface for most of the ClientScript functions so you get the same functionality as the ClientScript for code manipulation and you get the actual control which can be stuck into a page and provide markup based script injection into the page.&amp;nbsp; You can embed both physical url based scripts links as well as resource links so it's possible to consistently embed scripts from both. The control also detects script duplication and only embeds only a single script reference into the page so it's easier for Markup and Code injected scripts to not generate multiple script references. It's possible to add a script like jQuery into the page and ensure that it doesn't get embedded twice for example.&lt;/p&gt;
&lt;p&gt;But ScriptManager is also very problematic. First it's a .NET 3.5 component so it's really and add-on and not universally available. There's also no easy way to detect whether ScriptManager is available in a page without using the ScriptManager in the first place (&lt;a href="http://www.west-wind.com/WebLog/posts/10246.aspx"&gt;it's possible but it's a royal pain&lt;/a&gt;). ScriptManager also requires a control on the page - it's not a standalone API which complicates using it in generic solutions especially since only one ScriptManager is allowed per page. Finally last but not least the control arrogantly throws the Microsoft ASP.NET AJAX ClientLibraries into the page (at least 28k of compressed script for minmal support) with no option to turn that off. If you're not using ASP.NET AJAX like myself the last thing I want is to get a bunch of scripts I'm not using thrown into my page.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Custom Script Manager&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;My first thought when seeing ScriptManager's issue of AJAX script loading was to subclass the control. It's easy to turn off the AJAX script injection, but unfortunately ScriptManager can't be subclassed in such a way that it still provides Intellisense because apparently Visual Studio's Intellisense for script Intellisense is hard coded to look for ScriptManager's specific properties. Script Intellisense is quite useful so ontop of the other shortcomings of SM I decided to just build my own.&lt;/p&gt;
&lt;p&gt;The control I ended up with is similar in concept, but with better focus on externally hosted scripts.&lt;/p&gt;
&lt;div style="font-size: 10pt; background: white; color: black; font-family: courier new"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ww&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;wwScriptContainer&lt;/span&gt; &lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;="scripts"&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;RenderMode&lt;/span&gt;&lt;span style="color: blue"&gt;="Header"&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Scripts&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt; &lt;span style="color: red"&gt;Src&lt;/span&gt;&lt;span style="color: blue"&gt;="Scripts/jquery.js"&lt;/span&gt;&amp;nbsp; &lt;span style="color: red"&gt;Resource=&lt;/span&gt;&lt;span style="color: blue"&gt;"jquery"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt; &lt;span style="color: red"&gt;Src&lt;/span&gt;&lt;span style="color: blue"&gt;="Scripts/ui.core.js"&lt;/span&gt;&amp;nbsp; &lt;span style="color: red"&gt;AllowMinScript&lt;/span&gt;&lt;span style="color: blue"&gt;="true"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt; &lt;span style="color: red"&gt;Src&lt;/span&gt;&lt;span style="color: blue"&gt;="Scripts/ui.draggable.js"&lt;/span&gt;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/pre&gt;&lt;pre style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt; &lt;span style="color: red"&gt;Src&lt;/span&gt;&lt;span style="color: blue"&gt;="Scripts/wwscriptlibrary.js"&lt;/span&gt;&amp;nbsp; &lt;span style="color: red"&gt;Resource=&lt;/span&gt;&lt;span style="color: blue"&gt;"wwscriptlibrary"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Script&lt;/span&gt; &lt;span style="color: red"&gt;Resource&lt;/span&gt;&lt;span style="color: blue"&gt;="ControlResources.Menu.js"&lt;/span&gt; &lt;span style="color: red"&gt;ResourceControl&lt;/span&gt;&lt;span style="color: blue"&gt;="txtInput"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Scripts&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ww&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;wwScriptContainer&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The control can either be embedded into the page or there's a .Current property that can be used from code&amp;nbsp; that either finds an existing instance or creates a new control and adds it to the page dynamically which is useful for controls that want to embed resources. This gives a single API both for markup and code based embedding. &lt;/p&gt;
&lt;p&gt;While working on this there were are a few other things that came up as useful: Optional automatic usage of minimized scripts (.min.js) extensions, abillity to embed all scripts into the page header (or inline, or as scripts) rather than adding into the page, the ability to order scripts by inserting at the end or beginning, as well as determining on a per script basis where it renders (Header, Script, Inline or InheritedFromControl) all of which gives some additional control both for markup and code behind. You can also embed resources but use reference a script on disk (for example in a central Web location) in order to still get Intellisense. The latter isn't as nice as ScriptManager's ability to just work off resource Urls, but at least it allows for some Intellisense of resource based scripts.&lt;/p&gt;
&lt;p&gt;The format of the control is a bit ugly - I had to use the &amp;lt;scripts&amp;gt; and &amp;lt;script&amp;gt; tags in order to get Intellisense in pages to work because this is the only way I could figure out how to get Intellisense to work. Using custom prefixes (required for new controls) immediately breaks VS JavaScript Intellisense. The result is that I had to use HtmlControls for the script which means there's no Intellisense. Bummer, but the syntax is easy enough to look up.&lt;/p&gt;
&lt;p&gt;This is a relatively new control for me and so far I've only used it with one project, but so far this looks promising. But of course this too is a non-standard way of working - it requires using this control instead of script embedding into headers, but at least the syntax of this control is pretty much based on standard Script tags. In fact, for basic scripts the syntax is identical (ie. like the draggable.js) above. If this sounds interesting to you let me know in comments and I can post more info on this control.&lt;/p&gt;
&lt;p&gt;But this control is also not a generic solution. It works well for my internal purposes as well as for a few customers I'm working with but it's not totally satisfying either because of the inconsistencies in Visual Studio. And forcing developers to use a custom control is not my idea of a good design either, but for me at least this control addresses a few key scenarios like script compression and programmatic control over scripts and resources.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;No Clear Winning Solution&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;So as you can see I have no clear answers that satisfy even my own requirements entirely. For the most part I'm still embedding scripts straight into the HTML header and hope for the best. The biggest issues I've run into have been conflicts between some of my controls that rely on script resources and scripts loaded through the header with duplicate loads. Most of this is mitigated by my controls which can disable script loading and defer to manually loaded scripts when needed (ie. all script resources are properties and can be loaded either from resources, a url or not all injected by the control). Tracking these things down though can be time consuming. I'm not there yet but I think using hte above control is likely to fix that problem, but for generic controls requiring this control container to be used is probably a hard sell.&lt;/p&gt;
&lt;p&gt;Even the wwScriptContainer control&amp;nbsp; doesn't address the versioning and update scenarios although it does help with managing resource and file based script injection both for markup and controls (at least for my own controls). So I'm still searching for sanity and some input on what works for others who are heavily using scripts.&lt;/p&gt;
&lt;p&gt;So, dear reader, what are your thoughts on this issue? Are you also fighting with script management hell? Do you use scripts from raw files, or do you use resources? What about for controls that use these scripts? And how do you manage these scripts if they get used across solutions? There are lots of options available but which ones make the most sense to you and why?&lt;/p&gt;
&lt;p&gt;I'd love to hear your thoughts.&lt;/p&gt;&lt;div class='comment commentauthor' style='border: none 0px;min-height:30px;'&gt;&lt;small&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/WebLog/ShowPosts.aspx?Category=HTML'&gt;HTML&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;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%2f413878.aspx&amp;title=Inclusion+of+JavaScript+Files"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f413878.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RickStrahl?a=qL3fRO"&gt;&lt;img src="http://feeds.feedburner.com/~a/RickStrahl?i=qL3fRO" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=FQVitJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=FQVitJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=D2ZGqj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=D2ZGqj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=4h3WnJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=4h3WnJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=rooTKj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=rooTKj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=ouiIjJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=ouiIjJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=84BCnj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=84BCnj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/328787847" height="1" width="1"/&gt;</description>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=RickStrahl&amp;itemurl=http%3A%2F%2Fwest-wind.com%2Fweblog%2Fposts%2F413878.aspx</feedburner:awareness><feedburner:origLink>http://west-wind.com/weblog/posts/413878.aspx</feedburner:origLink></item>
    <item>
      <title>Permissions Denied to get Property location.toString in FireFox 3</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/325196649/408827.aspx</link>
      <guid isPermaLink="false">408827_200807022031</guid>
      <pubDate>Wed, 02 Jul 2008 20:31:15 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/408827.aspx#Comments</comments>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=408827</wfw:commentRss>
      <category>HTML</category>
      <description>&lt;p&gt;Since installing FireFox 3, including earlier betas,&amp;nbsp; I've been getting errors that show up on a host of different sites - including on my own. It appears that most errors are related to&amp;nbsp; the advertising that runs here and more specifically Flash ads.&amp;nbsp; While the errors are harmless enough and don't actually cause any noticeable problems on pages or even the Flash ads, they do show as annoying errors in &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;The errors displayed look something like this and they always seem to point at some baffling unrelated JavaScript content in the HTML document:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.west-wind.com/WebLog/images/200801/WindowsLiveWriter/PermissionsDeniedtoge.toStringinFireFox3_13CAE/PermissionDeniedLocationString_2.png"&gt;&lt;img border="0" alt="PermissionDeniedLocationString" src="http://www.west-wind.com/WebLog/images/200801/WindowsLiveWriter/PermissionsDeniedtoge.toStringinFireFox3_13CAE/PermissionDeniedLocationString_thumb.png" width="550" height="198"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;The above screen shot is from Yahoo's news page to a linked item and is clearly related to Flash components as evidenced by the script filename.&amp;nbsp; What's interesting is that these errors started showing up only with FireFox 3.0. Running IE or FireFox 2.x never ran into these issues, so it appears that this is related to some new security feature in FF3.&lt;/p&gt; &lt;p&gt;The problem is fairly prevalent and it seems that most of it is related to content loaded into separate frames - as many ad services do. Google Adsense seems a frequent problem as well as other services that use Flash or even HTML based content typically loaded into iFrames dynamically.&lt;/p&gt; &lt;p&gt;I've been searching around for some time trying to determine what causes this error and maybe more interestingly what security setting controls this particular error. I hate seeing errors - any errors in Firebug pop up. While there are a number of hits on this particular error none seem to point at a the same situation I'm seeing here namely with Flash components.&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000" size="1"&gt;[updated - comments where down this morning and a few emailed comments where sent]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;As Dave Ward pointed out in a message earlier today while my comments where down, the issue seems to be related to changes in the Flash player and cross domain policy. He sent this link that explains more and indeed adding a crossdomain.xml file solves the issue:&lt;/p&gt; &lt;p&gt;&lt;a href="http://willperone.net/Code/as3error.php"&gt;http://willperone.net/Code/as3error.php&lt;/a&gt; &lt;p&gt;Still this is not very satisfying. While that solves the problem for me on my site (in testing only), it doesn't address the errors on other sites that haven't updated their cross-domain files.&lt;/p&gt;&lt;div class='comment commentauthor' style='border: none 0px;min-height:30px;'&gt;&lt;small&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/WebLog/ShowPosts.aspx?Category=HTML'&gt;HTML&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%2f408827.aspx&amp;title=Permissions+Denied+to+get+Property+location.toString+in+FireFox+3"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f408827.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RickStrahl?a=17vNlE"&gt;&lt;img src="http://feeds.feedburner.com/~a/RickStrahl?i=17vNlE" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=k3vliJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=k3vliJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=2mnPQj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=2mnPQj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=b5ZPKJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=b5ZPKJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=PUAzwj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=PUAzwj" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=PRRCzJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=PRRCzJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=b0mHkj"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=b0mHkj" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/325196649" height="1" width="1"/&gt;</description>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=RickStrahl&amp;itemurl=http%3A%2F%2Fwest-wind.com%2Fweblog%2Fposts%2F408827.aspx</feedburner:awareness><feedburner:origLink>http://west-wind.com/weblog/posts/408827.aspx</feedburner:origLink></item>
    <item>
      <title>Customers and POs from Hell</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/322500057/405143.aspx</link>
      <guid isPermaLink="false">405143_200806290942</guid>
      <pubDate>Sun, 29 Jun 2008 09:42:58 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/405143.aspx#Comments</comments>
      <slash:comments>14</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=405143</wfw:commentRss>
      <category>ISV</category>
      <category>Personal</category>
      <description>&lt;P&gt;I do most of my business with credit cards and while I realize that the CC companies and merchant banks are making a killing off my sales with merchant percentages, the convenience of having credit card processing fully automated to the point that I often have to do absolutely nothing other than review orders is well worth the extra expense.Credit card processing (or PayPal processing for that matter) is convenient for the customer too, but most of all the process can be mostly automated.&amp;nbsp; I run through my online store and a related offline application which is a very slightly modified version of our West Wind &lt;A href="http://www.west-wind.com/westwindwebstore/" target=WebStore&gt;West Wind Web Store&lt;/A&gt; to do all my order processing. The process is completely automated except for most software updates which require manual validation. I'm using Authorize.NET with a merchant hookup through MerchantPlus and with this setup life is good. The review rate for these transactions for declines or other CC processing issues is under 2%.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;I wish it was all that easy&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;So the vast majority of customers (a little over 95%) use Credit Cards and things are straight forward and easy. There's an occasional W9 form that gets sent but other than that the process is nearly automatic with minimal effort and immediate confirmation for customers without any need for their interaction either.&lt;/P&gt;
&lt;P&gt;But the remaining 5% tend to be highly problematic and take more time to process than the entire rest of the bunch combined (and that's including the occasional chargeback research). The remainder tends to be Purchase Orders with each customer requiring their own setup and configuration. Most of the time these customers will throw you a PO that is 5 pages long with Vendor number, department numbers, not one but 3 PO numbers and instructions of what the order has to look like for the privilege of serving them. To top it off a few recent POs had a Politically Correct questionnaire for Equal Opportunity regulations that apply to my business.&lt;/P&gt;
&lt;P&gt;Now I may be extremely arrogant in this, but WTF do these people think? I realize some organizations have strict rules and regulations for how order processing needs to proceed and I can relate to that as long as the requested information is reasonable. Obviously some sort of manual filling is in order and that's understandable. There are organizations that have a clean way to provide vendors to submit the necessary information and provide POs that are 1 page or 2 pages with instructions that can be easily followed and completed in a few minutes and without fuss. No problem there. &lt;/P&gt;
&lt;P&gt;But it's those 'other' customers (generally they are the mega institutions or government orders) that are painful and require an hour's worth of form filling and additional research just to satisfy their need for information that is ridiculously out of sync with any requirement for the order processing. Companies and Government organizations that try to completely force their order processing on the vendor for some small one off order seems ridiculous. Here's an example: A couple of days I ago I got this PO Order that was literally 10 faxed pages. In addition, this document required a separate W9 form filled out for a purchase of $199. The whole process was to be set up as a vendor. I sent the form back and told them to send back a 'short form' or&amp;nbsp; order online or else forget it. A few emails went back and forth and in the end they did actually order online by credit card - not out of good manners, but because it saved them $15. So let's see here - these guys value $15 more than the forms they sent me to fill out. &lt;/P&gt;
&lt;P&gt;Arrogant, yeah I know. I should be so happy to have customers. But seriously I draw the line when I see customers whose bureaucracy has crazily gone out of hand and is going to make me pay for it. If I had filled out that form I would have easily spent an hour looking up all the various references required some of which did not - uhm feel exactly appropriate. Equal Opportunity Rights are OK to a point, but please give me a break on whether this really makes a difference in placing orders with vendors especially when it's a trivial amount of money on a one off order.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Charging Extra&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Because there's a lot of extra effort involved with Purchase Orders we charge a $15 surcharge for their processing. The amount doesn't really cover the extra time spent for any but the most simple PO's, but it's meant to discourage use of POs. It used to be that using credit cards caused a surcharge because of the extra fees a vendor pays (which is actually not allowed by CC merchant contracts), but I actually feel that the opposite is true in this day and age: A credit card transaction typically is cheaper if paper work and routing and excessive back and forth chatter can be avoided. The $15 surcharge is an added incentive NOT to use POs.&lt;/P&gt;
&lt;P&gt;Some companies get really pissed off at the surcharge to the effect that they simply cross it off the PO and send it back - without note or comment. And so the PO goes back and forth a few times. And more time's a wastin'.&lt;/P&gt;
&lt;P&gt;Another vendor (a reseller) recently contacted me and wanted to know where their order confirmation was for a third party customer. I had filled and submitted their Purchase Order request form ( a 'mere' 5 pages) and sent it back. In the next 3 days I heard from 3 different people in the same vendor company, but not one had confirmed my original PO form that I had requested verification for. Nor did they ever reply to any of my requests like who the heck to send the final download links to. In the end I had talked to 5 DIFFERENT people in the company and only heard back from one last manager who finally figured out to cc the others in an email in his department and get their story straight. Apparently all the bureaucracy is confusing even these folks in THEIR OWN office! It took the customer starting to complain loudly (apparently they had paid the vendor before the PO was even approved) to get these folks off their butt and finally resolve the issue. Incredible.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Is it Arrogant?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Stuff like this happens all the time. 90% of effort for 3% of total order volume. &lt;/P&gt;
&lt;P&gt;So here's the question of the day: Is it truly arrogant to say "Enough is enough!" and hold the customer to provide a reasonable PO request? Or is the customer always King no matter how screwed up their process is and whether it's a giant waste of time (both theirs and mine)?&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Granted my case is special because I'm a one man shop and handle everything myself. A bigger organization can probably manage better because there's a full time person to handle order processing and knows how to deal with all the crazy forms, but regardless it's still a massive waste of time when 3% of customers cause 90% of the order processing work load - it's so rare that it really sticks out when it happens. In the end it depends some on the amount of an order, but on small orders especially, I tend to give customers some grief to keep things simple that a form can be filled out in a timely manner or tell them to - well, "Stick it!"&lt;/P&gt;
&lt;P&gt;Got any good PO stories? I know I have a couple of repeat customers who have personally apologized for the PO practices of their company (one in a rather rather humorous way recently that I unfortunately can't print here)... &lt;/P&gt;&lt;div class='comment commentauthor' style='border: none 0px;min-height:30px;'&gt;&lt;small&gt;&lt;div&gt;Posted in &lt;b&gt;&lt;a href='/WebLog/ShowPosts.aspx?Category=ISV'&gt;ISV&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href='/WebLog/ShowPosts.aspx?Category=Personal'&gt;Personal&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%2f405143.aspx&amp;title=Customers+and+POs+from+Hell"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.west-wind.com%2fweblog%2fposts%2f405143.aspx" border='0' alt='kick it on DotNetKicks.com' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feeds.feedburner.com/~a/RickStrahl?a=vcSSPp"&gt;&lt;img src="http://feeds.feedburner.com/~a/RickStrahl?i=vcSSPp" border="0"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=QEE79I"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=QEE79I" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=6lPM4i"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=6lPM4i" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=7d3qXI"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=7d3qXI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=wdWxai"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=wdWxai" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=faBXRI"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=faBXRI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/RickStrahl?a=DOsbZi"&gt;&lt;img src="http://feeds.feedburner.com/~f/RickStrahl?i=DOsbZi" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RickStrahl/~4/322500057" height="1" width="1"/&gt;</description>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=RickStrahl&amp;itemurl=http%3A%2F%2Fwest-wind.com%2Fweblog%2Fposts%2F405143.aspx</feedburner:awareness><feedburner:origLink>http://west-wind.com/weblog/posts/405143.aspx</feedburner:origLink></item>
    <item>
      <title>Updated jQuery and WCF 3.5 JSON Samples posted</title>
      <link>http://feeds.feedburner.com/~r/RickStrahl/~3/319688990/400990.aspx</link>
      <guid isPermaLink="false">400990_200806251258</guid>
      <pubDate>Wed, 25 Jun 2008 12:58:59 GMT</pubDate>
      <dc:creator>Rick Strahl</dc:creator>
      <comments>http://west-wind.com/weblog/posts/400990.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://west-wind.com/weblog/commentrss.aspx?id=400990</wfw:commentRss>
      <category> ASP.NET</category>
      <category>JavaScript</category>
      <category>jQuery</category>
      <category>WCF</category>
      <description>&lt;p&gt;Since I last posted &lt;a href="http://www.west-wind.com/WebLog/posts/336745.aspx"&gt;my DevConnection samples&lt;/a&gt;, there have been a number of changes with jQuery and jQuery Ui. During the conference and for some of my own applications I'd been using intermediate builds of jQuery in order to be able to use the latest versions of jQuery.ui beta which at the time didn't work with the last public release (mainly because of the intearation of the Dimensions Plug-in into the jQuery core).&lt;/p&gt; &lt;p&gt;I've updated all the jQuery samples as well as the WCF 3.5 JSON samples from those sessions and fixed a number of small issues I didn't have time to address for the conference at the time. &lt;/p&gt; &lt;p&gt;You can download the samples and slides here:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;jQuery Samples and Slides:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.west-wind.com/files/conferences/jquery.zip"&gt;http://www.west-wind.com/files/conferences/jquery.zip&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;WCF 3.5 REST and JSON Samples:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.west-wind.com/files/conferences/wcfRest.zip"&gt;htt