<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.encosia.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.encosia.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">

<channel>
	<title>Encosia</title>
	
	<link>http://encosia.com</link>
	<description>ASP.NET and AJAX code, ideas, and examples.</description>
	<pubDate>Wed, 07 May 2008 17:54:30 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.encosia.com/Encosia" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">654672</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.feedburner.com</feedburner:feedburnerHostname><item>
		<title>Highslide JS .NET Updated (v0.7)</title>
		<link>http://encosia.com/2008/04/29/highslide-js-net-updated-v07/</link>
		<comments>http://encosia.com/2008/04/29/highslide-js-net-updated-v07/#comments</comments>
		<pubDate>Tue, 29 Apr 2008 19:19:42 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[Highslide]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=75</guid>
		<description><![CDATA[An update to Highslide JS .NET is available today.  I recommend that everyone upgrade, to benefit from the memory leak fixes in the latest Highslide JS.
v0.7 (4/29/2008)

Updated embedded Highslide version to 3.3.17.
Improved caption rendering, using inline caption divs.  This should result in more semantic markup, pairing your captions with your images.
Added HighslideManager property: [...]]]></description>
			<content:encoded><![CDATA[<p>An update to <strong>Highslide JS .NET</strong> is available today.  I recommend that everyone upgrade, to benefit from the memory leak fixes in the latest Highslide JS.</p>
<p><strong>v0.7</strong> (4/29/2008)</p>
<ul>
<li>Updated embedded Highslide version to 3.3.17.</li>
<li>Improved caption rendering, using inline caption divs.  This should result in more semantic markup, pairing your captions with your images.</li>
<li>Added HighslideManager property:  <strong>NumberOfImagesToPreload</strong>.  This allows you to control how many images are automatically preloaded.</li>
<li>Added HighslideManager property:  <strong>FadeInOut</strong>.  When true, this fades the enlargement in and out as it&#8217;s resizing.</li>
<li>Added HighslideManager property:  <strong>RenderScriptInPlace</strong>.  This allows you to control where on the page the Highslide JS script is inserted in your page.</li>
<li>Updated download to include a sample site, to make it a little easier to get up and running quickly.</li>
</ul>
<p>As always, the latest version is available on the <a href="http://encosia.com/downloads/highslide-js-net/">Highslide JS .NET project page</a>.</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=1zlkxg"><img src="http://feeds.encosia.com/~f/Encosia?i=1zlkxg" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=DfIBeG"><img src="http://feeds.encosia.com/~f/Encosia?i=DfIBeG" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=KYhjHG"><img src="http://feeds.encosia.com/~f/Encosia?i=KYhjHG" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=l7Fxeg"><img src="http://feeds.encosia.com/~f/Encosia?i=l7Fxeg" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=FTuUpg"><img src="http://feeds.encosia.com/~f/Encosia?i=FTuUpg" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/04/29/highslide-js-net-updated-v07/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F04%2F29%2Fhighslide-js-net-updated-v07%2F</feedburner:awareness></item>
		<item>
		<title>Why you should not place your whole site in an UpdatePanel</title>
		<link>http://encosia.com/2008/04/23/why-you-should-not-place-your-whole-site-in-an-updatepanel/</link>
		<comments>http://encosia.com/2008/04/23/why-you-should-not-place-your-whole-site-in-an-updatepanel/#comments</comments>
		<pubDate>Wed, 23 Apr 2008 08:59:07 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[Performance]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=74</guid>
		<description><![CDATA[Three significant reasons why you should avoid using an UpdatePanel to encapsulate your entire site and provide "navigation" by refreshing content areas.]]></description>
			<content:encoded><![CDATA[<p>Perhaps due to its ubiquitous presence in web based email services, implementing asynchronous site navigation is frequently a design requirement when building AJAX based sites.  Unfortunately, the also ubiquitous UpdatePanel is chosen to accomplish this far too often.</p>
<p>I&#8217;d like to take a moment to strongly recommend against doing that.</p>
<p>I&#8217;m going to explain what I believe are the three most dangerous drawbacks inherent to UpdatePanel based navigation:  <strong>Performance degradation</strong>, <strong>usability concerns</strong>, and <strong>lack of maintainability</strong>.</p>
<p><em>Note:  I would add SEO concerns to the list of drawbacks, but I&#8217;m going to assume that anyone who cares about SEO knows better than to use an UpdatePanel for content they wish to be indexed.</em></p>
<h3>Performance degradation (read: obliteration)</h3>
<p>As I&#8217;ve mentioned in the past, <a href="http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/">UpdatePanels endanger the performance of your application</a>.  While the UpdatePanel does have its place, the underpinning for your entire site&#8217;s navigation system is not one of those places.  A quick comparison makes this clear.  </p>
<p>This is what happens when you use a LinkButton to trigger an UpdatePanel refresh:</p>
<ul>
<li>The PageRequestManager catches the event on the client side and runs through its pre-request events, while preparing an XmlHttpRequest object.</li>
<li>This XHR object makes an HTTP POST request to the server.  This request includes every form field on the page, including the entire ViewState (even for areas of the page not being updated).</li>
<li>ASP.NET creates a new instance of the Page class, using the ViewState and other POST data to restore its state to that of your last postback or partial postback.</li>
<li>The Page runs through its lifecycle and returns its rendered HTML result to the ASP.NET AJAX framework.</li>
<li>The ASP.NET AJAX framework parses out the specific HTML section(s) that will be sent back to refresh the UpdatePanel(s) affected by the partial postback.</li>
<li>This response is combined with other control information, such as JavaScript content registered via the ScriptManager&#8217;s various methods, and sent back to the XHR object.</li>
<li>The PageRequestManger parses the response and updates the DOM to refresh the affected UpdatePanel(s).</li>
<li>Finally, the browser renders the updated DOM.</li>
</ul>
<p>Using a traditional HTML &lt;a&gt; link to navigate the browser to a different page:</p>
<ul>
<li>The browser makes a simple HTTP GET request to the URL.</li>
<li>ASP.NET creates a new instance of that Page.</li>
<li>The Page runs through its lifecycle and returns its rendered HTML.</li>
<li>The browser receives this HTML and renders it.</li>
</ul>
<p>As you can see, these two methods of requesting an update are two very different animals.  Not only is the partial postback pipeline far more complex, but some of the additional steps are potentially <strong>very expensive</strong>.</p>
<p><a href="http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/">Perceived performance is usually more important than actual performance</a>.  The UpdatePanel is not going to bring this to the table.</p>
<p>When considering performance, it&#8217;s also important to keep in mind that what seems fast enough in a local development environment may be devastatingly slow when deployed.  It is <em>essential</em> that you test your application&#8217;s performance over a WAN connection early and often.</p>
<h3>Usability?  What&#8217;s that?</h3>
<p>When you choose to discard the browser&#8217;s navigation system for one of your own creation, you also discard usability benefits that you might not be aware of.  Each individual browser provides progress indication and other subtle cues that your users have spent years becoming accustomed to.  Replacing that with a foreign system is jarring and needlessly introduces an artificial learning curve.</p>
<p>Further, you suddenly make yourself responsible for providing accurate progress indication in every browser.  When&#8217;s the last time you tested your UpdateProgress template on an iPhone?  Yeah, me either.</p>
<p>Personally, I make heavy use of the <a href="https://addons.mozilla.org/en-US/firefox/addon/137" target="_blank" rel="nofollow">DragAndGo</a> add-on for regular browsing.  When I come across a site that won&#8217;t allow me to toss its links into tabs this way, I typically won&#8217;t spend much of my time fighting with it.  </p>
<p>Needless to say, the LinkButton&#8217;s __doPostBack href quickly sends me packing.</p>
<h3>Who will you find to maintain it?  Not me!</h3>
<p>Your single, monolithic page will add tremendous maintenance overhead to your entire application.   Worse still, many of the problems don&#8217;t present immediately, so it&#8217;s easy to start down this road and find yourself painted into a corner later.  </p>
<p>For just a taste of what you could be in for, consider these potential pitfalls:</p>
<ul>
<li>Imagine if every time you made a modification to page A, you had to carefully avoid breaking pages B-Z and <strong>then regression test them all</strong>.</li>
<li>Imagine when your designer(s) want to make changes to the site, but its HTML is locked inside this single page structure.  That interaction tends to already be painful enough even with a traditional page structure.  Complicating it further is going to be a non-starter in just about any organization.</li>
<li>Imagine trying to work in a multi-developer environment at all.
<ul>
<li>If you&#8217;re using VSS or TFS for source control, one developer checking out for a minor edit would lock the rest of the team out of the entire presentation layer.</li>
<li>If you&#8217;re using something like SVN, nearly every change to the presentation layer would result in a merge operation, instead of a simple commit.</li>
</ul>
</li>
</ul>
<p>Once you start thinking about the potential maintenance issues, you can probably think of a dozen more on your own.  I won&#8217;t belabor the point.</p>
<h3>Conclusion</h3>
<p>Hopefully, this laundry list of drawbacks will save you from making the mistake of using an UpdatePanel for site navigation.  If not, I hope that it has at least raised your awareness about the problems that lie ahead, so that you may prepare for them now.</p>
<p>So how should you do it instead?  <strong>Iframes</strong>.  It&#8217;s that simple.</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=Iq6NoFg"><img src="http://feeds.encosia.com/~f/Encosia?i=Iq6NoFg" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=zCPyvNG"><img src="http://feeds.encosia.com/~f/Encosia?i=zCPyvNG" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=0DkuCXG"><img src="http://feeds.encosia.com/~f/Encosia?i=0DkuCXG" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=nj3Lx2g"><img src="http://feeds.encosia.com/~f/Encosia?i=nj3Lx2g" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=aGHTWlg"><img src="http://feeds.encosia.com/~f/Encosia?i=aGHTWlg" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/04/23/why-you-should-not-place-your-whole-site-in-an-updatepanel/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F04%2F23%2Fwhy-you-should-not-place-your-whole-site-in-an-updatepanel%2F</feedburner:awareness></item>
		<item>
		<title>Why do ASP.NET AJAX page methods have to be static?</title>
		<link>http://encosia.com/2008/04/16/why-do-aspnet-ajax-page-methods-have-to-be-static/</link>
		<comments>http://encosia.com/2008/04/16/why-do-aspnet-ajax-page-methods-have-to-be-static/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 07:33:31 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[OO]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=72</guid>
		<description><![CDATA[A thorough explanation of why ASP.NET AJAX page methods must be static methods, including information about the Page class, ViewState serialization, and what a static method actually is.]]></description>
			<content:encoded><![CDATA[<p><img src="/blog/media/images/static-spark.jpg" width="178" height="260" style="margin-right: 10px; margin-top: 4px; float: left;" />Dozens of variations on the title of this post are some of the most common searches that bring people here to Encosia.  Unfortunately, the search engines all point to a post that doesn&#8217;t answer the question.  It&#8217;s also a frequent question raised on the ASP.NET message boards, typically without a satisfactory answer provided.</p>
<p>However, it is an important question, the answer to which is important to understand.  So, in an attempt to fill in this gap for the searchers and perhaps preemptively help others, I want to proceed to answer it as thoroughly as possible without overly complicating the whole business.</p>
<p>In order to do this, we&#8217;ll have to take a brief tour of WebForms, including:</p>
<ul>
<li>Understanding what the Page class is, and why we have it.</li>
<li>One specific thing that the Page class does for us.</li>
<li>How this is accomplished, behind the scenes.</li>
<li>What the static keyword entails, when used with a method.</li>
<li>Finally, why page methods must be static.</li>
</ul>
<p><em>Note:  Please bear in mind that I have taken great liberties in simplifying these concepts down to only what is necessary to answer the central question.  What I will show you is conceptually accurate, but some of the implementation details are much more complex than what you will see here.</em></p>
<h3>Understanding what the Page class is, and why we have it</h3>
<p>Contorting the stateless HTTP protocol to accommodate ASP.NET&#8217;s WebForm paradigm was a considerable task for the ASP.NET team to accomplish.  On top of that, going from the inline execution model of ASP classic to the event-driven model of ASP.NET also required major changes.</p>
<p>As such, the ubiquitous WebForms <a href="http://msdn2.microsoft.com/en-us/library/ms178138.aspx" rel="nofollow" target="_blank">Page class</a> was created to solve these various problems.  Take this snippet, for example:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #0600FF;">public</span> partial <span style="color: #FF0000;">class</span> _Default : <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">UI</span>.<span style="color: #0000FF;">Page</span> 
<span style="color: #000000;">&#123;</span>
  <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">void</span> Page_Load<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span> 
  <span style="color: #000000;">&#123;</span> 
    <span style="color: #008080; font-style: italic;">// Hello World.</span>
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>I&#8217;m sure you&#8217;re familiar with the Page_Load event.  The very first ASP.NET code example you were exposed to probably involved the Page_Load event.  How about this portion of it though?</p>

<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #0600FF;">public</span> partial <span style="color: #FF0000;">class</span> _Default : <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">UI</span>.<span style="color: #0000FF;">Page</span></pre></div></div>

<p>To get you started quickly, those examples may not have explained that part very well (if at all).  Later, after you get up and running, it can be easy to simply gloss over this line as cruft that comes with writing an ASP.NET page.</p>
<p>What this declaration means is that your code extends the Page class.  Because of this, your code will include the functionality of the entire ASP.NET Page class, instead of standing on its own and requiring you to implement the mundane details.</p>
<p>If you&#8217;re more familiar with something like ASP classic or PHP, you can think of this Page inheritance as being functionally similar to a powerful include file that you use site-wide.</p>
<h3>One of the Page&#8217;s most powerful features:  Persistence</h3>
<p>The Page brings a lot to the table.  However, to answer the question of why page methods must be static, we need to focus on <strong>persistence</strong>.  </p>
<p>Consider this example:</p>

<div class="wp_syntax"><div class="code"><pre class="asp"><span style="color: #a31515;">&lt;asp:Label</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;Label1&quot;</span> /<span style="color: #a31515;">&gt;</span>
<span style="color: #a31515;">&lt;asp:Button</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;Button1&quot;</span> <span style="color: #cc0000;">OnClick</span>=<span style="color: #0000cc;">&quot;Button1_Click&quot;</span> /<span style="color: #a31515;">&gt;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">void</span> Button1_Click<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  Label1.<span style="color: #0000FF;">Text</span> += DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Each time the button is clicked, the label will have the current time and date appended to its current contents.  Even this elementary example illustrates how the WebForms Page automatically provides persistence for us.</p>
<p>We take for granted that the Page will provide us this Label1 object after an HTTP POST from the browser.  We also assume that it will automatically have a Text property with that Label&#8217;s current value.  </p>
<p>However, this data would not normally be included in the POST data sent to the server.  Only form elements are sent from the browser.  The Label renders as a span element, which means that its state is <em>not</em> POSTed by the browser.</p>
<p>So, how does the Page provide us with this data anyway?  Persistence.</p>
<h3>Understanding how the Page does this</h3>
<p>To implement this encompassing layer of persistence, the <strong>ViewState</strong> was created. </p>
<p>Each time a page is rendered to the browser, the Page serializes the state of its controls and then includes that information in the returned HTML, via a hidden form field named <strong>__ViewState</strong>.  When a postback occurs, this hidden field can then be de-serialized to create an instance of the Page in the same state that it was at the end of the last request.</p>
<p>Oversimplifying, you can envision this constructor being used to re-instantiate the Page, at the beginning of every postback:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp">Page _Default = <span style="color: #008000;">new</span> Page<span style="color: #000000;">&#40;</span>Request<span style="color: #000000;">&#91;</span><span style="color: #808080;">&quot;__ViewState&quot;</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">&#41;</span>;</pre></div></div>

<p>In our example above, the Page created through that process would look something like this after one postback:</p>
<p><img src="/blog/media/images/page-instance-watches.png" style="border: 1px solid #333;" /></p>
<p>This re-instantiation of the Page from the ViewState is what keeps the entire WebForms machine rolling, postback after postback.</p>
<h3>What does it mean that a method is static?</h3>
<p>A static method is simply one that is disassociated from any instance of its containing class.  The more common alternative is an instance method, which is a method whose result is dependent on the state of a particular instance of the class it belongs to.</p>
<p>For example, both of these statements would return precisely the same string, but accomplish it through different types of methods:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #008080; font-style: italic;">// ToString() is an instance method of the DateTime class.</span>
<span style="color: #008080; font-style: italic;">//  Its result depends on the value of each DateTime instance.</span>
<span style="color: #0600FF;">return</span> DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #008080; font-style: italic;">// String.Format is a static method of the String class.</span>
<span style="color: #008080; font-style: italic;">//  Its result is not related to any instance of the String.</span>
<span style="color: #0600FF;">return</span> <span style="color: #FF0000;">String</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;{0}&quot;</span>, DateTime.<span style="color: #0000FF;">Now</span><span style="color: #000000;">&#41;</span>;</pre></div></div>

<p>The key difference to understand is that a static method can be called <em>without</em> setting up a proper instance of the class it belongs to.  </p>
<p>In a sense, it is <strong>a stateless method</strong>.</p>
<h3>So, why do page method calls have to be static?</h3>
<p>If you&#8217;re implementing page methods, you&#8217;re probably well aware of their excellent performance.  They are <a href="http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/">especially performant compared to the UpdatePanel&#8217;s partial postbacks</a>.</p>
<p>They are efficient largely because they do not require the ViewState to be POSTed and they do not create an instance of the Page, while partial postbacks do both of these things.  As we now know, a page method couldn&#8217;t create an instance of the page even if desired, since the ViewState isn&#8217;t provided in the request.</p>
<p><strong>This is exactly why they must be marked as static</strong>.  They cannot interact with the instance properties and methods of your Page class, because a page method call creates no instance of the Page or any of its controls.</p>
<p>Page methods are roughly equivalent to shorthand for standalone web services.  In fact, the ScriptManager even calls them exactly as it would a regular web service.</p>
<h3>Conclusion</h3>
<p>While forcing the page method to be static is primarily due to technical reasons, I would suggest that it&#8217;s actually a <em>good</em> thing.  If page methods transmitted the ViewState along with their request, in order to instantiate the Page, they would immediately lose a majority of their benefit.</p>
<p>Forcing the method to be static is necessary to confer most of the benefits of using page methods.  Sure, it would be nice to be able to access control properties directly from within page methods, but not at the expense of transmitting volumes of extraneous data about every other control on the page.  </p>
<p>Instead of fighting against this limitation, I say <strong>embrace efficiency</strong>.</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=kv7RKLg"><img src="http://feeds.encosia.com/~f/Encosia?i=kv7RKLg" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=m6M6RlG"><img src="http://feeds.encosia.com/~f/Encosia?i=m6M6RlG" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=rZq7BIG"><img src="http://feeds.encosia.com/~f/Encosia?i=rZq7BIG" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=Eiev6bg"><img src="http://feeds.encosia.com/~f/Encosia?i=Eiev6bg" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=b8XWN0g"><img src="http://feeds.encosia.com/~f/Encosia?i=b8XWN0g" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/04/16/why-do-aspnet-ajax-page-methods-have-to-be-static/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F04%2F16%2Fwhy-do-aspnet-ajax-page-methods-have-to-be-static%2F</feedburner:awareness></item>
		<item>
		<title>Using jQuery to Consume ASP.NET JSON Web Services</title>
		<link>http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/</link>
		<comments>http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/#comments</comments>
		<pubDate>Thu, 27 Mar 2008 08:00:41 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Performance]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/</guid>
		<description><![CDATA[An overview of consuming ASP.NET web services that are JSON serialized by the ASP.NET AJAX extensions, including a specific example of using jQuery to do so.]]></description>
			<content:encoded><![CDATA[<p><img src="http://encosia.com/blog/media/images/delayed-load-with-fade.gif" width="240" height="216"  style="border: 1px solid #000; margin-left: 15px; float: right;" /> In response to many of the articles here, I receive feedback asking how to achieve the same results without using ASP.NET AJAX.  As much as I&#8217;m a fan of ASP.NET AJAX, I must agree that its JavaScript payload can certainly be a drawback in some situations.</p>
<p>My recent <a href="http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/">deferred content loading</a> post is an excellent example of that.  I was using <a rel="nofollow" href="http://jquery.com/">jQuery</a> for presentational effects, <em>and</em> using a ScriptManager to call a web service.  Loading the JavaScript for both frameworks was a bit counterproductive, since the whole point was to improve initial load time.</p>
<p>In this post, I intend to correct that.  </p>
<p>First, I&#8217;ll cover the <strong>two requirements</strong> necessary when calling an ASMX web service that&#8217;s being JSON serialized by the ASP.NET AJAX extensions.  Then, I&#8217;ll show you <strong>how to do this with jQuery</strong>.  Finally, I&#8217;ll <strong>update the deferred content loading example</strong> accordingly.</p>
<h3>Additional security when calling JSON serialized services</h3>
<p>A security feature of ASP.NET web services that are JSON serialized through the ASP.NET AJAX extensions is that they must be requested in a specific way.  This is an important deterrent against your services being used in XSS attacks.  <strong>Scott Guthrie</strong> has <a href="http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx">a great post providing detailed information</a> on the particulars.  It boils down to is two things:</p>
<ul>
<li>The request must be an HTTP POST request</li>
<li>The request&#8217;s content-type must be:  &#8220;application/json; charset=utf-8&#8243;</li>
</ul>
<p>When you register and call a web service through ASP.NET AJAX&#8217;s ScriptManager, you may safely enjoy blissful ignorance of these requirements.  The framework transparently handles everything for you.</p>
<p>However, if you want to use a third party AJAX framework to request the JSON serialized output, you may run into trouble due to these security features.</p>
<h3>How to make jQuery jump through these hoops</h3>
<p>The solution is a bit less intuitive than using the ScriptManager or what you would normally expect from jQuery.  Using jQuery&#8217;s getJSON() would make sense, but it unfortunately meets neither of the above security criteria.</p>
<p>The most reliable way that I&#8217;ve found is to use jQuery.ajax() as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">$.<span style="color: #006600;">ajax</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span>
  type: <span style="color: #3366CC;">&quot;POST&quot;</span>,
  url: <span style="color: #3366CC;">&quot;WebService.asmx/WebMethodName&quot;</span>,
  beforeSend: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>xhr<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    xhr.<span style="color: #006600;">setRequestHeader</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;Content-type&quot;</span>, 
                         <span style="color: #3366CC;">&quot;application/json; charset=utf-8&quot;</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #66cc66;">&#125;</span>,
  dataType: <span style="color: #3366CC;">&quot;json&quot;</span>
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Setting the request type to POST is self explanatory.  </p>
<p>The beforeSend option is the key.  It allows you to handle a jQuery event very similar to the PageRequestManager&#8217;s InitializeRequest event.  The function is called with a reference to the actual XmlHttpRequest object about to be used in the AJAX call.  This allows us to set its content-type to what the ASP.NET AJAX framework requires, just before the request is made.</p>
<p><em>Note: jQuery.ajax() does have a contentType option, but it will be ignored if there is no data included in the POST.  For read-only requests, this will cause the call to unexpectedly fail.</em></p>
<h3>Putting it all together</h3>
<p>Now that we know how to call the web service, appropriately modifying the original example is easy.  Here&#8217;s the new ASPX code:</p>

<div class="wp_syntax"><div class="code"><pre class="asp"><span style="color: #660000;">&lt;div</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;Container&quot;</span><span style="color: #a31515;">&gt;</span>
  <span style="color: #660000;">&lt;div</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;RSSBlock&quot;</span><span style="color: #a31515;">&gt;</span>
    <span style="color: #660000;">&lt;div</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;RSSContent&quot;</span> <span style="color: #cc0000;">class</span>=<span style="color: #0000cc;">&quot;loading&quot;</span>&gt;&lt;/div&gt;
  <span style="color: #660000;">&lt;/div&gt;</span>
&nbsp;
  <span style="color: #660000;">&lt;div</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;Content&quot;</span><span style="color: #a31515;">&gt;</span>
    &lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing...<span style="color: #660000;">&lt;/p&gt;</span>
  <span style="color: #660000;">&lt;/div&gt;</span>
<span style="color: #660000;">&lt;/div&gt;</span>
&nbsp;
<span style="color: #660000;">&lt;script</span> <span style="color: #cc0000;">type</span>=<span style="color: #0000cc;">&quot;text/javascript&quot;</span> src=<span style="color: #0000cc;">&quot;jquery-1.2.3.min.js&quot;</span>&gt;&lt;/script&gt;
<span style="color: #660000;">&lt;script</span> <span style="color: #cc0000;">type</span>=<span style="color: #0000cc;">&quot;text/javascript&quot;</span> src=<span style="color: #0000cc;">&quot;Default.js&quot;</span>&gt;&lt;/script&gt;</pre></div></div>

<p>Notice that I&#8217;ve placed the JavaScript references below the rest of the page&#8217;s content.  Since browsers block while requesting, loading, and executing JavaScript, it makes sense to defer that until as late as possible.  This will serve to further boost the page&#8217;s perceived performance.</p>
<p>Finally, the jQuery code to call the web service and appropriately handle its result:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">$<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  $.<span style="color: #006600;">ajax</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span>
    type: <span style="color: #3366CC;">&quot;POST&quot;</span>,
    url: <span style="color: #3366CC;">&quot;RSSReader.asmx/GetRSSReader&quot;</span>,
    beforeSend: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>xhr<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
      xhr.<span style="color: #006600;">setRequestHeader</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;Content-type&quot;</span>, 
                           <span style="color: #3366CC;">&quot;application/json; charset=utf-8&quot;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span>,
    dataType: <span style="color: #3366CC;">&quot;json&quot;</span>,
    success: <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>msg<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
      <span style="color: #009900; font-style: italic;">// Hide the fake progress indicator graphic.</span>
      $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#RSSContent'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">removeClass</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'loading'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
      <span style="color: #009900; font-style: italic;">// Insert the returned HTML into the &lt;div&gt;.</span>
      $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#RSSContent'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">html</span><span style="color: #66cc66;">&#40;</span>msg.<span style="color: #006600;">d</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span>
  <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<h3>Conclusion:  Is it worth it?</h3>
<p>By using jQuery to call the web service directly, <strong>we&#8217;ve eliminated over 100 KB of JavaScript</strong> and <strong>three extra HTTP requests</strong>.  The ASP.NET AJAX client side framework accounted for over half of the original example&#8217;s total download size, and those three extra HTTP requests unnecessarily delayed the progress indicator.</p>
<p>That may not sound like much, but it&#8217;s significant.  When it comes to loading speed and responsiveness, users do not perceive changes linearly.  Fractions of a second make the difference between a site that feels sluggish and one that appears responsive.</p>
<h3>A word about web services</h3>
<p>Web services are <em>great</em> tools that afford you substantial flexibility.  It&#8217;s important not to overlook them.</p>
<p>You&#8217;ve no doubt seen many AJAX examples that involve using the XmlHttpRequest to request the output of a specially designed page, resulting in CSV or otherwise arbitrarily formatted data instead of HTML.  For instance, I&#8217;ve noticed that a lot of the auto-complete plugins for jQuery expect this sort of kludge.  </p>
<p>I believe that to be a short-sighted and counterproductive way to do things.</p>
<p>Web services have often been maligned in the past, due to the XML bloat associated with SOAP.  However, JSON makes this drawback a thing of the past.  <a href="http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/">JSON is very lightweight</a>, making it ideal for structured AJAX communication.  With the inefficiencies of SOAP neutralized, I think the power and flexibility of web services cannot be overstated.</p>
<p>For example, if I decide to move my sites from WebForms to MVC, there is a large amount of functionality encapsulated in web services that I won&#8217;t have to worry about recoding or redesigning.  It&#8217;s a great feeling to have that flexibility and ease of reuse.</p>
<p>When used well, I think web services are to WebForms what object oriented programming was to procedural and functional programming.</p>
<h3>Try it for yourself:  download the source</h3>
<p>The full example&#8217;s source code (ASP.NET 3.5 required):</p>
<p><a href="http://encosia.com/samples/jQuery-JSON-call.zip"><img src="http://encosia.com/blog/images/download-bar-jQuery-JSON.png" alt="Download source: jQuery-JSON-call.zip (33kb)" width="492" height="46"/></a></p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=t8K9VUf"><img src="http://feeds.encosia.com/~f/Encosia?i=t8K9VUf" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=2Dz5JOF"><img src="http://feeds.encosia.com/~f/Encosia?i=2Dz5JOF" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=Av5jnJF"><img src="http://feeds.encosia.com/~f/Encosia?i=Av5jnJF" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=zGwv9Of"><img src="http://feeds.encosia.com/~f/Encosia?i=zGwv9Of" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=7I6QnPf"><img src="http://feeds.encosia.com/~f/Encosia?i=7I6QnPf" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F03%2F27%2Fusing-jquery-to-consume-aspnet-json-web-services%2F</feedburner:awareness></item>
		<item>
		<title>Why my ASP.NET AJAX forms are never submitted twice</title>
		<link>http://encosia.com/2008/03/04/why-my-aspnet-ajax-forms-are-never-submitted-twice/</link>
		<comments>http://encosia.com/2008/03/04/why-my-aspnet-ajax-forms-are-never-submitted-twice/#comments</comments>
		<pubDate>Tue, 04 Mar 2008 10:00:26 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/2008/03/04/why-my-aspnet-ajax-forms-are-never-submitted-twice/</guid>
		<description><![CDATA[A few examples of how to use getElementsByTagName and/or jQuery, in conjunction with ASP.NET AJAX, to easily disable all Button controls on a page or logical groups; to prevent duplicate submissions during partial postbacks.]]></description>
			<content:encoded><![CDATA[<p><img src="/blog/media/images/disable-multiple-buttons.gif" style="float: right; margin-left: 15px; margin-top: 3px;" height="256" width="108" />The overzealous double-clickers amongst our users often make it desirable to temporarily disable the controls that trigger server side processing.  Previously, I’ve shown you how to <a href="http://encosia.com/2007/04/17/disable-a-button-control-during-postback/">disable a button during a postback</a>, how to <a href="http://encosia.com/2007/01/16/css-style-as-ajax-progress-indicator/">disable a button during a partial postback</a>, and even written a <a href="http://encosia.com/downloads/postback-ritalin/">server control</a> to automate the latter.</p>
<p>However, what if you wanted to be more thorough and <strong>disable all of the buttons on a page</strong>?</p>
<p>In this post, I&#8217;m going to show you how to do just that.  I&#8217;ll also show you how to <strong>disable only the buttons in the UpdatePanel raising the event</strong>.  Finally, for the jQuery users out there, I&#8217;ll show you how to <strong>simplify the process down to one line of code</strong>.</p>
<h3>Building a demonstration page</h3>
<p>To demonstrate this technique, we&#8217;re going to need a page with several buttons that generate partial postbacks.  An expanded version of the typical <em>Hello World</em> AJAX sample (a la DateTime.Now) will get the job done:</p>

<div class="wp_syntax"><div class="code"><pre class="asp"><span style="color: #a31515;">&lt;asp:ScriptManager</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">ID</span>=<span style="color: #0000cc;">&quot;ScriptManager1&quot;</span> /<span style="color: #a31515;">&gt;</span>
&nbsp;
<span style="color: #a31515;">&lt;asp:UpdatePanel</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">ID</span>=<span style="color: #0000cc;">&quot;UpdatePanel1&quot;</span><span style="color: #a31515;">&gt;</span>
  <span style="color: #660000;">&lt;ContentTemplate&gt;</span>
      <span style="color: #a31515;">&lt;asp:Button</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">ID</span>=<span style="color: #0000cc;">&quot;Button1&quot;</span> <span style="color: #cc0000;">Text</span>=<span style="color: #0000cc;">&quot;Button1&quot;</span> 
        <span style="color: #cc0000;">onclick</span>=<span style="color: #0000cc;">&quot;Button1_Click&quot;</span> /<span style="color: #a31515;">&gt;</span>
      <span style="color: #a31515;">&lt;asp:Literal</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">ID</span>=<span style="color: #0000cc;">&quot;Literal1&quot;</span> /<span style="color: #a31515;">&gt;</span>
&nbsp;
      <span style="color: #a31515;">&lt;asp:Button</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">ID</span>=<span style="color: #0000cc;">&quot;Button2&quot;</span> <span style="color: #cc0000;">Text</span>=<span style="color: #0000cc;">&quot;Button2&quot;</span> 
        <span style="color: #cc0000;">onclick</span>=<span style="color: #0000cc;">&quot;Button2_Click&quot;</span> /<span style="color: #a31515;">&gt;</span>
      <span style="color: #a31515;">&lt;asp:Literal</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">ID</span>=<span style="color: #0000cc;">&quot;Literal2&quot;</span> /<span style="color: #a31515;">&gt;</span>
  <span style="color: #660000;">&lt;/ContentTemplate&gt;</span>
<span style="color: #a31515;">&lt;/asp:UpdatePanel&gt;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">void</span> Button1_Click<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Threading</span>.<span style="color: #0000FF;">Thread</span>.<span style="color: #0000FF;">Sleep</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1500</span><span style="color: #000000;">&#41;</span>;
  Literal1.<span style="color: #0000FF;">Text</span> = DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">void</span> Button2_Click<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Threading</span>.<span style="color: #0000FF;">Thread</span>.<span style="color: #0000FF;">Sleep</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1500</span><span style="color: #000000;">&#41;</span>;
  Literal2.<span style="color: #0000FF;">Text</span> = DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span></pre></div></div>

<h3>Using getElementsByTagName to find the buttons</h3>
<p>You&#8217;re probably familiar with the JavaScript function <strong>getElementById</strong> and our handy $get shortcut for it, but how about <strong>GetElementsByTagName</strong>?  </p>
<p>This useful JavaScript function returns an array of elements matching a specified HTML tag name.  For example, document.getElementsByTagName(&#8217;div&#8217;) would return an array of every &lt;div&gt; on the page.</p>
<p>Since we know that ASP.NET Button controls render as &lt;input type=&#8221;submit&#8221;&gt; elements, the solution is clear.  We can use a BeginRequest and EndRequest handler to put that to work during a partial postback:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> BeginRequest<span style="color: #66cc66;">&#40;</span>sender, args<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #009900; font-style: italic;">// Get an array of all the input elements on the page.</span>
  <span style="color: #003366; font-weight: bold;">var</span> inputs = document.<span style="color: #006600;">getElementsByTagName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Loop through the elements and check each one's type.</span>
  <span style="color: #009900; font-style: italic;">//  if it's a submit type element, disable it.</span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span>element <span style="color: #000066; font-weight: bold;">in</span> inputs<span style="color: #66cc66;">&#41;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>inputs<span style="color: #66cc66;">&#91;</span>element<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">type</span> == <span style="color: #3366CC;">'submit'</span><span style="color: #66cc66;">&#41;</span>
      inputs<span style="color: #66cc66;">&#91;</span>element<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">disabled</span> = <span style="color: #003366; font-weight: bold;">true</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> EndRequest<span style="color: #66cc66;">&#40;</span>sender, args<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>  
  <span style="color: #009900; font-style: italic;">// Get an array of all the input elements on the page.</span>
  <span style="color: #003366; font-weight: bold;">var</span> inputs = document.<span style="color: #006600;">getElementsByTagName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #66cc66;">&#41;</span>;  
&nbsp;
  <span style="color: #009900; font-style: italic;">// Loop through the elements and check each one's type.</span>
  <span style="color: #009900; font-style: italic;">//  if it's a submit type element, enable it.  </span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span>element <span style="color: #000066; font-weight: bold;">in</span> inputs<span style="color: #66cc66;">&#41;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>inputs<span style="color: #66cc66;">&#91;</span>element<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">type</span> == <span style="color: #3366CC;">'submit'</span><span style="color: #66cc66;">&#41;</span>
      inputs<span style="color: #66cc66;">&#91;</span>element<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">disabled</span> = <span style="color: #003366; font-weight: bold;">false</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h3>Limiting the technique to a single UpdatePanel&#8217;s Buttons</h3>
<p>A nice feature of getElementsByTagName is that it can be used to search the children of most any element.  So, if you&#8217;d like to limit this functionality to a particular region of a page, that&#8217;s easy too.</p>
<p>An UpdatePanel renders its ContentTemplate as a &lt;div&gt; element.  With that in mind, the trick here is to call getElementsByTagName on the &lt;div&gt;&#8217;s children instead of on the entire document.  To do so, only a few changes to the code are needed:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> BeginRequest<span style="color: #66cc66;">&#40;</span>sender, args<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #009900; font-style: italic;">// Find the ID of the UpdatePanel raising the partial postback.</span>
  <span style="color: #003366; font-weight: bold;">var</span> panelID = sender._postBackSettings.<span style="color: #006600;">panelID</span>.<span style="color: #006600;">split</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;|&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Using that ID, get a reference to that UpdatePanel's div.</span>
  <span style="color: #003366; font-weight: bold;">var</span> sendingPanel = document.<span style="color: #006600;">getElementById</span><span style="color: #66cc66;">&#40;</span>sendingPanelID<span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Get an array of all the input elements in that div.</span>
  <span style="color: #003366; font-weight: bold;">var</span> inputs = sendingPanel.<span style="color: #006600;">getElementsByTagName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Loop through the elements and check each one's type.</span>
  <span style="color: #009900; font-style: italic;">//  if it's a submit type element, disable it.</span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span>element <span style="color: #000066; font-weight: bold;">in</span> inputs<span style="color: #66cc66;">&#41;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>inputs<span style="color: #66cc66;">&#91;</span>element<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">type</span> == <span style="color: #3366CC;">'submit'</span><span style="color: #66cc66;">&#41;</span>
      inputs<span style="color: #66cc66;">&#91;</span>element<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">disabled</span> = <span style="color: #003366; font-weight: bold;">true</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> EndRequest<span style="color: #66cc66;">&#40;</span>sender, args<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #009900; font-style: italic;">// Find the ID of the UpdatePanel raising the partial postback.</span>
  <span style="color: #003366; font-weight: bold;">var</span> panelID = sender._postBackSettings.<span style="color: #006600;">panelID</span>.<span style="color: #006600;">split</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;|&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Using that ID, get a reference to that UpdatePanel's div.</span>
  <span style="color: #003366; font-weight: bold;">var</span> sendingPanel = document.<span style="color: #006600;">getElementById</span><span style="color: #66cc66;">&#40;</span>sendingPanelID<span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Get an array of all the input elements in that div.</span>
  <span style="color: #003366; font-weight: bold;">var</span> inputs = sendingPanel.<span style="color: #006600;">getElementsByTagName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Loop through the elements and check each one's type.</span>
  <span style="color: #009900; font-style: italic;">//  if it's a submit type element, disable it.  </span>
  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span>element <span style="color: #000066; font-weight: bold;">in</span> inputs<span style="color: #66cc66;">&#41;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>inputs<span style="color: #66cc66;">&#91;</span>element<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">type</span> == <span style="color: #3366CC;">'submit'</span><span style="color: #66cc66;">&#41;</span>
      inputs<span style="color: #66cc66;">&#91;</span>element<span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">disabled</span> = <span style="color: #003366; font-weight: bold;">false</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>As you can see, it&#8217;s basically the same code.  It takes a slight bit more work to find which UpdatePanel raised the partial postback, but it&#8217;s identical after that.  </p>
<p>You can use this same method to target the children of any control that renders as an HTML element.  This includes Accordion panels, Wizard steps, TabPanel containers, and many others.  If you&#8217;re unsure how a particular control renders, <a href="http://encosia.com/2007/03/06/debug-and-explore-aspnet-ajax-with-firebug/">using FireBug to inspect your page</a> can dramatically accelerate the discovery process.</p>
<h3>jQuery could become your new best friend</h3>
<p>If you haven&#8217;t tried using jQuery with ASP.NET AJAX before, I highly recommend it.  To give you an idea of why, here&#8217;s how you could use jQuery to re-write the first example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> BeginRequest<span style="color: #66cc66;">&#40;</span>sender, args<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'input[@type=submit]'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'disabled'</span>, <span style="color: #003366; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> EndRequest<span style="color: #66cc66;">&#40;</span>sender, args<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'input[@type=submit]'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'disabled'</span>, <span style="color: #003366; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>That&#8217;s all there is to it.  Really.  </p>
<p>The UpdatePanel targeted functionality can also be accomplished with similarly concise jQuery code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> BeginRequest<span style="color: #66cc66;">&#40;</span>sender, args<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> panelID = sender._postBackSettings.<span style="color: #006600;">panelID</span>.<span style="color: #006600;">split</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;|&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
  $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#'</span> + panelID + <span style="color: #3366CC;">' input[@type=submit]'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'disabled'</span>, <span style="color: #003366; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> EndRequest<span style="color: #66cc66;">&#40;</span>sender, args<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> panelID = sender._postBackSettings.<span style="color: #006600;">panelID</span>.<span style="color: #006600;">split</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;|&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
  $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#'</span> + panelID + <span style="color: #3366CC;">' input[@type=submit]'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'disabled'</span>, <span style="color: #003366; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>It&#8217;s hard not to love that!</p>
<h3>Conclusion:  We&#8217;ve only just begun</h3>
<p>In your own implementation, you might want to limit the technique to only a certain, focal UpdatePanel (or other container) instead of any that raises a postback.  You might also want to add a few UI improvements, such as <strong>changing button text</strong>, <strong>blurring the buttons</strong>, or <strong>changing the mouse cursor</strong> during the partial postback.</p>
<p>All of this is possible, with only slight modifications to the sample code.  In fact, the download below includes the blurring (it makes a noticeable difference in FireFox).</p>
<p>Additionally, keep in mind that this code contains no error handling.  I&#8217;m assuming that there are buttons on the page, buttons in every UpdatePanel, and that a button inside an UpdatePanel raises every event.</p>
<p>In production, you should definitely be more careful than I have been here.  At very least, check that the array is actually an array before trying to iterate over it.</p>
<h3>Source download</h3>
<p>Finally, here is the source code download for the full demonstration page, including the client script for the second example:</p>
<p><a href="/samples/disable-buttons.zip"><img src="/blog/images/download-bar-disable-buttons.png"  height="46" width="492" alt="Download Source:  disable-buttons.zip (4kb)" title="source code download link" /></a></p>
<h3>Shameless plug</h3>
<p>If you like the idea of having this functionality, but don&#8217;t like the idea of having to implement it, then keep an eye out for the next version of <a href="http://encosia.com/downloads/postback-ritalin/">PostBack Ritalin</a>.  I&#8217;ll be integrating this into it as an optional feature in the next release.</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=XYqcdNf"><img src="http://feeds.encosia.com/~f/Encosia?i=XYqcdNf" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=S7KxuXF"><img src="http://feeds.encosia.com/~f/Encosia?i=S7KxuXF" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=p5tVxkF"><img src="http://feeds.encosia.com/~f/Encosia?i=p5tVxkF" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=q5tqCyf"><img src="http://feeds.encosia.com/~f/Encosia?i=q5tqCyf" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=cjC9Tvf"><img src="http://feeds.encosia.com/~f/Encosia?i=cjC9Tvf" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/03/04/why-my-aspnet-ajax-forms-are-never-submitted-twice/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F03%2F04%2Fwhy-my-aspnet-ajax-forms-are-never-submitted-twice%2F</feedburner:awareness></item>
		<item>
		<title>Boost ASP.NET performance with deferred content loading</title>
		<link>http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/</link>
		<comments>http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/#comments</comments>
		<pubDate>Tue, 05 Feb 2008 14:00:32 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Performance]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/</guid>
		<description><![CDATA[A comprehensive example of how to improve the perceived speed of your pages, by implementing user controls to encapsulate secondary content and then deferring them until primary content is displayed.]]></description>
			<content:encoded><![CDATA[<p><img src="http://encosia.com/blog/media/images/delayed-net-requests.png" alt="FireBug graph of net requests" width="492" height="149" style="margin-bottom: 10px;" /><br />
When rolled into the page life cycle of an ASP.NET WebForm, that red bar is one of your application&#8217;s greatest enemies.  No matter how well you optimize the rest of the page, even one slow task can become the sole factor determining a user&#8217;s perception of the entire page&#8217;s performance.</p>
<p>In this post, I&#8217;m going to show you one way to circumvent that problem.  By placing ancillary content in user controls and delaying their load until the core page content has been displayed, you can drastically improve perceived performance.</p>
<p>When broken down into digestible chunks, the technique is easy to implement and lends your application a level of polish that your users are sure to appreciate.  The four steps required to accomplish this will be: <strong>building the user control</strong>, statelessly <strong>rendering the control as HTML</strong>, <strong>providing progress indication</strong>, and using ASP.NET AJAX to <strong>request and inject that HTML</strong>.</p>
<h3>Building the user control</h3>
<p>First, we need some slow-loading, auxiliary content to encapsulate in a user control.  For this example, that&#8217;s going to be a minimal RSS feed reader widget that displays the most recent posts from this site.</p>
<p>The key activity here is retrieving <a href="http://feeds.feedburner.com/Encosia" rel="nofollow">my RSS feed</a> and querying it for some basic information.  To expedite this, I&#8217;m going to use one of ASP.NET 3.5&#8217;s great new features:  <strong>LINQ to XML</strong>.  LINQ really makes short work of this normally tedious task.  It still blows me away every time I use it.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">void</span> Page_Load<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  XDocument feedXML = 
    XDocument.<span style="color: #0000FF;">Load</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;http://feeds.encosia.com/Encosia&quot;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
  var feeds = from feed <span style="color: #0600FF;">in</span> feedXML.<span style="color: #0000FF;">Descendants</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;item&quot;</span><span style="color: #000000;">&#41;</span>
              select <span style="color: #008000;">new</span>
              <span style="color: #000000;">&#123;</span>
                Title = feed.<span style="color: #0000FF;">Element</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;title&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span>,
                Link = feed.<span style="color: #0000FF;">Element</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;link&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span>,
                Description = feed.<span style="color: #0000FF;">Element</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;description&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span>
              <span style="color: #000000;">&#125;</span>;
&nbsp;
  PostList.<span style="color: #0000FF;">DataSource</span> = feeds;
  PostList.<span style="color: #0000FF;">DataBind</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>To display this, I&#8217;m going to use another of ASP.NET 3.5&#8217;s new features, the <strong>ListView</strong> control:</p>

<div class="wp_syntax"><div class="code"><pre class="asp">&lt;asp:ListView <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">ID</span>=<span style="color: #0000cc;">&quot;PostList&quot;</span><span style="color: #a31515;">&gt;</span>
  &lt;LayoutTemplate&gt;
    &lt;ul&gt;
      &lt;asp:PlaceHolder <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span> <span style="color: #cc0000;">ID</span>=<span style="color: #0000cc;">&quot;itemPlaceholder&quot;</span> /<span style="color: #a31515;">&gt;</span>
    &lt;/ul&gt;
  &lt;/LayoutTemplate&gt;
  &lt;ItemTemplate&gt;
    &lt;li&gt;&lt;a href=<span style="color: #0000cc;">'&lt;%# Eval(&quot;Link&quot;) %&gt;'</span>&gt;&lt;%# Eval<span style="color: #006600; font-weight:bold">&#40;</span><span style="color: #0000cc;">&quot;Title&quot;</span><span style="color: #006600; font-weight:bold">&#41;</span> %&gt;&lt;/a&gt;&lt;br /<span style="color: #a31515;">&gt;</span>
      &lt;%# Eval<span style="color: #006600; font-weight:bold">&#40;</span><span style="color: #0000cc;">&quot;Description&quot;</span><span style="color: #006600; font-weight:bold">&#41;</span> %<span style="color: #a31515;">&gt;</span>          
    &lt;/li&gt;
  &lt;/ItemTemplate&gt;
&lt;/asp:ListView&gt;</pre></div></div>

<p><img src="http://encosia.com/blog/media/images/rss-feed-control.png" alt="Example of the RSS feed widget control" align="right" style="margin-left: 10px;" width="200" height="172" />With a little bit of CSS (included in the source download later), this results in something resembling the screenshot to the right.</p>
<p>The ListView comes in especially handy for our purposes here, because it gives you such effortless control over the rendered HTML.  When injecting generated HTML into a page, you really appreciate knowing exactly what markup to expect.</p>
<h3>Rendering the user control as HTML</h3>
<p>The next step is to create a web service that statelessly renders our user control as an HTML string.  By statelessly, I mean that we need to render this user control outside the context of an active ASP.NET Page instance, where user controls are normally intended to be used.</p>
<p>To solve that problem, you can create a temporary instance of the ASP.NET Page class, dynamically add the user control to it, and then execute it within the web service&#8217;s context.  Doing this turns out to be easier than it is to accurately describe:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp"><span style="color: #000000;">&#91;</span>WebMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> GetRSSReader<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">// Create a new Page and add the control to it.</span>
  Page page = <span style="color: #008000;">new</span> Page<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
  UserControl ctl = 
    <span style="color: #000000;">&#40;</span>UserControl<span style="color: #000000;">&#41;</span>page.<span style="color: #0000FF;">LoadControl</span><span style="color: #000000;">&#40;</span><span style="color: #808080;">&quot;~/RSSReaderControl.ascx&quot;</span><span style="color: #000000;">&#41;</span>;
  page.<span style="color: #0000FF;">Controls</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>ctl<span style="color: #000000;">&#41;</span>;
&nbsp;
  <span style="color: #008080; font-style: italic;">// Render the page and capture the resulting HTML.</span>
  StringWriter writer = <span style="color: #008000;">new</span> StringWriter<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
  HttpContext.<span style="color: #0000FF;">Current</span>.<span style="color: #0000FF;">Server</span>.<span style="color: #0000FF;">Execute</span><span style="color: #000000;">&#40;</span>page, writer, <span style="color: #0600FF;">false</span><span style="color: #000000;">&#41;</span>;
&nbsp;
  <span style="color: #008080; font-style: italic;">// Return that HTML, as a string.</span>
  <span style="color: #0600FF;">return</span> writer.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>You might worry about creating an entire Page instance for what is supposed to be a performance enhancing technique.  At first, I shared the same concern.</p>
<p>However, since our Page instance is created outside of the normal ASP.NET HTTP pipeline and only contains one control, the overhead is negligible.  The Page itself is fairly performant compared to all of the other work involved in a typical HTTP round-trip.</p>
<h3>Setting up the demonstration page</h3>
<p>To demonstrate, we&#8217;ll need a page with some fast-loading content to provide contrast.  Inside that, we can embed an empty DIV which will be used to accurately inject the user control&#8217;s rendered HTML.</p>

<div class="wp_syntax"><div class="code"><pre class="asp"><span style="color: #a31515;">&lt;asp:ScriptManager</span> <span style="color: #cc0000;">runat</span>=<span style="color: #0000cc;">&quot;server&quot;</span><span style="color: #a31515;">&gt;</span>
  <span style="color: #660000;">&lt;Services&gt;</span>
    <span style="color: #a31515;">&lt;asp:ServiceReference</span> <span style="color: #cc0000;">Path</span>=<span style="color: #0000cc;">&quot;~/RSSReader.asmx&quot;</span> /<span style="color: #a31515;">&gt;</span>
  <span style="color: #660000;">&lt;/Services&gt;</span>
  <span style="color: #660000;">&lt;Scripts&gt;</span>
    <span style="color: #a31515;">&lt;asp:ScriptReference</span> <span style="color: #cc0000;">Path</span>=<span style="color: #0000cc;">&quot;~/Default.js&quot;</span> /<span style="color: #a31515;">&gt;</span>
  <span style="color: #660000;">&lt;/Scripts&gt;</span>
<span style="color: #a31515;">&lt;/asp:ScriptManager&gt;</span>
<span style="color: #660000;">&lt;div</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;Container&quot;</span><span style="color: #a31515;">&gt;</span>
  <span style="color: #660000;">&lt;div</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;RSSBlock&quot;</span> <span style="color: #cc0000;">class</span>=<span style="color: #0000cc;">&quot;loading&quot;</span>&gt;&lt;/div&gt;
  <span style="color: #660000;">&lt;div</span> <span style="color: #cc0000;">id</span>=<span style="color: #0000cc;">&quot;Content&quot;</span><span style="color: #a31515;">&gt;</span>
    &lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing...<span style="color: #660000;">&lt;/p&gt;</span>
  <span style="color: #660000;">&lt;/div&gt;</span>
<span style="color: #660000;">&lt;/div&gt;</span></pre></div></div>

<p>As you can see, the RSSBlock DIV is initially assigned a CSS class of &#8220;loading&#8221;.  This is the CSS for the loading class:</p>

<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #6666ff;">.loading</span> <span style="color: #66cc66;">&#123;</span> 
  <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'progress-indicator.gif'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #993333;">center</span>; 
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p><img src="http://encosia.com/blog/media/images/rss-feed-progress-indicator.png" alt="Progress indicator displayed while the user control loads" align="left" style="margin-right: 10px;" width="150" height="129" />What this does is give us a bit of rudimentary progress indication.  Until we update it later, it will display an empty placeholder with an indicator.</p>
<p>You and I know that it&#8217;s a bit of a scam, but your users will never realize the progress indicator isn&#8217;t real.  I won&#8217;t tell if you won&#8217;t!</p>
<h3>Calling the web service from JavaScript</h3>
<p>Now that we&#8217;ve got a place to inject it, the final step is to retrieve the HTML rendering of our user control and insert it into the page.  ASP.NET AJAX takes all of the hard work out of this step:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">Sys.<span style="color: #006600;">Application</span>.<span style="color: #006600;">add_init</span><span style="color: #66cc66;">&#40;</span>AppInit<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> AppInit<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  RSSReader.<span style="color: #006600;">GetRSSReader</span><span style="color: #66cc66;">&#40;</span>OnSuccess, OnFailure<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> OnSuccess<span style="color: #66cc66;">&#40;</span>result<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #009900; font-style: italic;">// Remove the .loading CSS from the div, to remove the </span>
  <span style="color: #009900; font-style: italic;">//  progress indicator background.</span>
  Sys.<span style="color: #006600;">UI</span>.<span style="color: #006600;">DomElement</span>.<span style="color: #006600;">removeCssClass</span><span style="color: #66cc66;">&#40;</span>$get<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'RSSBlock'</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #3366CC;">'loading'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #009900; font-style: italic;">// Fill the div with the HTML generated from the user control.</span>
  $get<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'RSSBlock'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">innerHTML</span> = result;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> OnFailure<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #009900; font-style: italic;">// Do something if our callback fails.  Retry it, perhaps.</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Since it&#8217;s only a CSS class, disabling the progress indication is as simple as using removeCssClass to remove it from the DIV.  For more on removeCssClass, check out <a href="http://encosia.com/2008/01/09/4-aspnet-ajax-javascript-ui-functions-you-should-learn/">my recent article about ASP.NET AJAX&#8217;s client side UI methods</a>.</p>
<p>With the animated background removed, we are now free to insert the rendered HTML into the DIV&#8217;s innerHTML.  The end result is exactly the same as if we had placed the user control inside that DIV, without unnecessarily delaying the entire page load.</p>
<h3>Conclusion</h3>
<p>I think you&#8217;ll find that this technique is very powerful.  It allows you to leverage your existing knowledge of ASP.NET and its server controls as a robust templating solution for lightweight AJAX.  At the same time, it exudes the kind of professional usability that typically requires more tedious and less maintainable client side coding.</p>
<p>Note that there is not an UpdatePanel anywhere on this page.  Using this technique does not require relying on partial postbacks.  Not only does that improve performance, but also allows UpdatePanels elsewhere on the page to operate normally, while the deferred content loads.</p>
<p><a href="http://encosia.com/samples/uc-delay-load.zip" rel="nofollow"><img src="http://encosia.com/blog/images/download-bar-uc-delay-load.png" alt="Download source: uc-delay-load.zip (36kb)" width="492" height="46"/></a></p>
<p>Check out the full demonstration by downloading the source and running it yourself.  You really have to see it in action to truly appreciate it.  The download also includes at least one improvement that I didn&#8217;t have room to write about in this post.  Give it a try and let me know what you think.</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=a33Hepe"><img src="http://feeds.encosia.com/~f/Encosia?i=a33Hepe" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=eAXpKDE"><img src="http://feeds.encosia.com/~f/Encosia?i=eAXpKDE" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=DUA8CTE"><img src="http://feeds.encosia.com/~f/Encosia?i=DUA8CTE" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=EwNzLpe"><img src="http://feeds.encosia.com/~f/Encosia?i=EwNzLpe" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=M6FssEe"><img src="http://feeds.encosia.com/~f/Encosia?i=M6FssEe" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F02%2F05%2Fboost-aspnet-performance-with-deferred-content-loading%2F</feedburner:awareness></item>
		<item>
		<title>PostBack Ritalin Updated (v0.9)</title>
		<link>http://encosia.com/2008/01/30/postback-ritalin-updated-v09/</link>
		<comments>http://encosia.com/2008/01/30/postback-ritalin-updated-v09/#comments</comments>
		<pubDate>Thu, 31 Jan 2008 01:22:36 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[PostBack Ritalin]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/2008/01/30/postback-ritalin-updated-v09/</guid>
		<description><![CDATA[Another significant update to PostBack Ritalin is available today.  Changes include:
v0.9 (1/30/2008)

Resolved all remaining issues with master pages.  Nested naming containers should no longer cause any issues.
Added the ability to provide UpdatePanel specific WaitText and WaitImage properties for each MonitoredUpdatePanel.
Added correct handling for virtual paths in all WaitImage properties.
Added CSS to change cursor [...]]]></description>
			<content:encoded><![CDATA[<p>Another significant update to PostBack Ritalin is available today.  Changes include:</p>
<p><strong>v0.9</strong> (1/30/2008)</p>
<ul>
<li>Resolved all remaining issues with master pages.  Nested naming containers should no longer cause any issues.</li>
<li>Added the ability to provide UpdatePanel specific WaitText and WaitImage properties for each MonitoredUpdatePanel.</li>
<li>Added correct handling for virtual paths in all WaitImage properties.</li>
<li>Added CSS to change cursor style to &#8220;wait&#8221; when hovering over the disabled control.</li>
<li>General improvements to client side code.</li>
</ul>
<p>The download is available on the <a href="http://encosia.com/downloads/postback-ritalin/">PostBack Ritalin</a> page.</p>
<p>I have several more ASP.NET AJAX example posts and at least one book review in the pipeline.  January has just been a very busy month so far (it started with our primary web server&#8217;s RAID array crashing on New Year&#8217;s Eve, so you can imagine).  Stay tuned for more of what you&#8217;re used to here soon.</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=5nV29Od"><img src="http://feeds.encosia.com/~f/Encosia?i=5nV29Od" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=cH6xiKD"><img src="http://feeds.encosia.com/~f/Encosia?i=cH6xiKD" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=Q3RiZPD"><img src="http://feeds.encosia.com/~f/Encosia?i=Q3RiZPD" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=RJjAzsd"><img src="http://feeds.encosia.com/~f/Encosia?i=RJjAzsd" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=WJ7HxHd"><img src="http://feeds.encosia.com/~f/Encosia?i=WJ7HxHd" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/01/30/postback-ritalin-updated-v09/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F01%2F30%2Fpostback-ritalin-updated-v09%2F</feedburner:awareness></item>
		<item>
		<title>Highslide JS .NET Updated (v0.5)</title>
		<link>http://encosia.com/2008/01/11/highslide-js-net-updated-v05/</link>
		<comments>http://encosia.com/2008/01/11/highslide-js-net-updated-v05/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 01:29:38 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[Highslide]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/2008/01/11/highslide-js-net-updated-v05/</guid>
		<description><![CDATA[A small update to Highslide JS .NET is available today.  Changes include:
v0.5 (1/11/2008)

Updated embedded Highslide JS version to 3.3.6.
Cleaned up Alt and Title attribute handling.
Added TitleText property to HighslideImage.
Added LinkTarget property to HighslideImage.

The download is available on the Highslide JS .NET page, as always.
Summary of the changes
Previously, the thumbnail image&#8217;s Title and Alt text [...]]]></description>
			<content:encoded><![CDATA[<p>A small update to Highslide JS .NET is available today.  Changes include:</p>
<p><strong>v0.5</strong> (1/11/2008)</p>
<ul>
<li>Updated embedded Highslide JS version to 3.3.6.</li>
<li>Cleaned up Alt and Title attribute handling.</li>
<li>Added <strong>TitleText</strong> property to HighslideImage.</li>
<li>Added <strong>LinkTarget</strong> property to HighslideImage.</li>
</ul>
<p>The download is available on the <a href="http://encosia.com/downloads/highslide-js-net/">Highslide JS .NET</a> page, as always.</p>
<h3>Summary of the changes</h3>
<p>Previously, the thumbnail image&#8217;s Title and Alt text were hard coded, for reasons I cannot imagine.  Now, the base Image control&#8217;s AlternateText is respected.  If no AlternateText is supplied, then &#8220;Thumbnail image for FullImageURL&#8221; is used.</p>
<p>Another new property, TitleText, is added to allow you to add a Title to the image.  If omitted, no title is added.</p>
<p>Finally, a LinkTarget property is also added in this version.  This is a string value that is passed through to the &lt;a&gt; tag that encloses the thumbnail image.  </p>
<p>Normally, when a user clicks a thumbnail image with JavaScript disabled, the current page navigates to the FullImageURL.  You can use LinkTarget to specify something like &#8220;_new&#8221;, to cause non-JavaScript users to open the full images in a new window/tab instead.</p>
<h3>The future</h3>
<p>I&#8217;ve begun adding ITemplate support for customizing the control bar.  That will hopefully be done for the next build, in the near future.  </p>
<p>Aside from that, what other features would you like to see added or improved?  I&#8217;m completely open to suggestions, as long as they remain mostly within the current scope (e.g. I have no intention of turning it into a full-blown gallery control).</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=OKsXjEd"><img src="http://feeds.encosia.com/~f/Encosia?i=OKsXjEd" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=11odaOD"><img src="http://feeds.encosia.com/~f/Encosia?i=11odaOD" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=8SyKmLD"><img src="http://feeds.encosia.com/~f/Encosia?i=8SyKmLD" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=cbdFfWD"><img src="http://feeds.encosia.com/~f/Encosia?i=cbdFfWD" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=Dl7OvFd"><img src="http://feeds.encosia.com/~f/Encosia?i=Dl7OvFd" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=Ht8txjd"><img src="http://feeds.encosia.com/~f/Encosia?i=Ht8txjd" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/01/11/highslide-js-net-updated-v05/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F01%2F11%2Fhighslide-js-net-updated-v05%2F</feedburner:awareness></item>
		<item>
		<title>4 ASP.NET AJAX JavaScript UI methods you should learn</title>
		<link>http://encosia.com/2008/01/09/4-aspnet-ajax-javascript-ui-functions-you-should-learn/</link>
		<comments>http://encosia.com/2008/01/09/4-aspnet-ajax-javascript-ui-functions-you-should-learn/#comments</comments>
		<pubDate>Wed, 09 Jan 2008 15:15:40 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/2008/01/09/4-aspnet-ajax-javascript-ui-functions-you-should-learn/</guid>
		<description><![CDATA[A closer look at some of the ASP.NET AJAX client side framework's less utilized UI functionality.  Examples include CSS manipulation, measuring the size of a rendered element, and finding/changing the location of an element.]]></description>
			<content:encoded><![CDATA[<p>Wrapping up my series on some of ASP.NET AJAX&#8217;s less utilized client side functionality, this post will take a closer look at some of ASP.NET AJAX&#8217;s JavaScript UI helper functions.  These methods are great because they abstract away most of the tedious work that comes with supporting cross browser compatibility, leaving us with a nice, consistent API.</p>
<p>Specifically, I&#8217;m going to show you examples of using <strong>addCssClass</strong>, <strong>getBounds</strong>, <strong>getLocation</strong>, and <strong>setLocation</strong> to accomplish a few client side UI tasks.</p>
<h3>Easily adding and removing CSS classes</h3>
<p>A relatively underused feature of CSS allows you to directly apply multiple CSS classes to the same element.  For example, maybe you&#8217;ve got an online test and want to style the test results to display correct answers in green and incorrect ones in red.  This is one way you might do that:</p>

<div class="wp_syntax"><div class="code"><pre class="css"><span style="color: #6666ff;">.answerResult</span> <span style="color: #66cc66;">&#123;</span>  <span style="color: #000000; font-weight: bold;">font-weight</span>: <span style="color: #993333;">bold</span>; <span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.correct</span>      <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span>: <span style="color: #993333;">green</span>; <span style="color: #66cc66;">&#125;</span>
<span style="color: #6666ff;">.incorrect</span>    <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span>: <span style="color: #993333;">red</span>; <span style="color: #66cc66;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre>Answer #1: &lt;span class=&quot;answerResult correct&quot;&gt;correct&lt;/span&gt;
Answer #2: &lt;span class=&quot;answerResult incorrect&quot;&gt;incorrect&lt;/span&gt;</pre></div></div>

<p>This is a clean solution to the problem.  The markup is semantic and avoids repetition by splitting the highlight from the base styling.  However, if we need to manipulate this on the client side, it&#8217;s going to take more work than is ideal.</p>
<p>Luckily, the ASP.NET AJAX client side framework provides helper functions to alleviate that complexity.  DomElement&#8217;s <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementAddCssClassMethod.aspx">addCssClass</a> and <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementRemoveCssClassMethod.aspx">removeCssClass</a> are exactly what we need.  Assuming the span was given an ID of answerResult, this is all that would be necessary to dynamically add the CSS for a correct answer:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">Sys.<span style="color: #006600;">UI</span>.<span style="color: #006600;">DomElement</span>.<span style="color: #006600;">addCssClass</span><span style="color: #66cc66;">&#40;</span>$get<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'answerResult'</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #3366CC;">'correct'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>I often use this technique in production by creating CSS classes with the same names as the status states of a field&#8217;s range of values.  Then, when displaying that data, it&#8217;s trivially easy to also add some contextual styling with addCssClass.</p>
<h3>Determining the size of an element</h3>
<p>If you work on client side UI functionality long enough, you&#8217;re eventually going to want to determine the size of HTML elements at runtime.  This turns out to be no fun at all, if you want to do it accurately cross-browser.  Instead of suffering through that ordeal, you can use DomElement&#8217;s <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementGetBoundsMethod.aspx" target="_new" rel="nofollow">getBounds</a> method.  It returns an associative array with an element&#8217;s size and position.</p>
<p>For example, what if you&#8217;ve filled a GridView with an arbitrary amount of data and want to find out how tall it is?  How would you go about that?</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> height = Sys.<span style="color: #006600;">UI</span>.<span style="color: #006600;">DomElement</span>.<span style="color: #006600;">getBounds</span><span style="color: #66cc66;">&#40;</span>$get<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'GridView1'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">height</span>;</pre></div></div>

<p>It doesn&#8217;t get much easier than that, does it?</p>
<h3>Locating and moving an element</h3>
<p>The final methods that I want to take a look at are <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementGetLocationMethod.aspx">getLocation</a> and <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementSetLocationMethod.aspx">setLocation</a>.  After all, the next logical step after finding the size of something is figuring out where it&#8217;s at and moving it around.</p>
<p>For example, let&#8217;s say you want to move a div, SomeDiv, 75px to the right:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> loc = Sys.<span style="color: #006600;">UI</span>.<span style="color: #006600;">DomElement</span>.<span style="color: #006600;">getLocation</span><span style="color: #66cc66;">&#40;</span>$get<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'SomeDiv'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
Sys.<span style="color: #006600;">UI</span>.<span style="color: #006600;">DomElement</span>.<span style="color: #006600;">setLocation</span><span style="color: #66cc66;">&#40;</span>$get<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'SomeDiv'</span><span style="color: #66cc66;">&#41;</span>, loc.<span style="color: #006600;">x</span> + <span style="color: #CC0000;">75</span>, loc.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Throw it in a loop and you&#8217;ve got yourself a basic animation:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span>i = <span style="color: #CC0000;">1</span>; i &lt;= <span style="color: #CC0000;">75</span>; i++<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
  Sys.<span style="color: #006600;">UI</span>.<span style="color: #006600;">DomElement</span>.<span style="color: #006600;">setLocation</span><span style="color: #66cc66;">&#40;</span>$get<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'SomeDiv'</span><span style="color: #66cc66;">&#41;</span>, loc.<span style="color: #006600;">x</span> + i, loc.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<h3>Conclusion</h3>
<p>You probably aren&#8217;t going to use these functions as often as <a href="http://encosia.com/2007/11/15/exploring-one-of-ms-ajaxs-often-overlooked-features/">$addHandler</a> or the <a href="http://encosia.com/2007/12/04/work-smarter-ms-ajaxs-javascript-base-type-extensions/">base type extensions</a>.  However, when you do need them you&#8217;re going to be really glad you know about them.  They save a lot of work, and help to automatically ensure a level of cross browser compatibility that is tedious to constantly write from scratch.</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=LhdywPd"><img src="http://feeds.encosia.com/~f/Encosia?i=LhdywPd" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=vN8FzxD"><img src="http://feeds.encosia.com/~f/Encosia?i=vN8FzxD" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=UnwbrsD"><img src="http://feeds.encosia.com/~f/Encosia?i=UnwbrsD" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=IUtpqzD"><img src="http://feeds.encosia.com/~f/Encosia?i=IUtpqzD" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=iCPHg3d"><img src="http://feeds.encosia.com/~f/Encosia?i=iCPHg3d" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=gXPXE7d"><img src="http://feeds.encosia.com/~f/Encosia?i=gXPXE7d" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2008/01/09/4-aspnet-ajax-javascript-ui-functions-you-should-learn/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2008%2F01%2F09%2F4-aspnet-ajax-javascript-ui-functions-you-should-learn%2F</feedburner:awareness></item>
		<item>
		<title>Best of 2007: 5 most popular posts (and contest winners)</title>
		<link>http://encosia.com/2007/12/21/best-of-2007-5-most-popular-posts-and-contest-winners/</link>
		<comments>http://encosia.com/2007/12/21/best-of-2007-5-most-popular-posts-and-contest-winners/#comments</comments>
		<pubDate>Fri, 21 Dec 2007 18:05:35 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
		
		<category><![CDATA[AJAX]]></category>

		<category><![CDATA[ASP.NET]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://encosia.com/2007/12/21/best-of-2007-5-most-popular-posts-and-contest-winners/</guid>
		<description><![CDATA[As of today, the site is exactly one year old.  What a year it has been!
I would like to sincerely thank every one of you for making this past year such a blast.  Without all of your great comments, emails, links, and kicks, I doubt that I would have been motivated enough to [...]]]></description>
			<content:encoded><![CDATA[<p>As of today, the site is exactly one year old.  <strong>What a year it has been!</strong></p>
<p>I would like to sincerely thank every one of you for making this past year such a blast.  Without all of your great comments, emails, links, and kicks, I doubt that I would have been motivated enough to keep putting in all the work that it takes to run this site.</p>
<p>I would also like to especially thank <a href="http://joeon.net">Joe Stagner</a>, <a href="http://weblogs.asp.net/scottgu/">Scott Guthrie</a>, and the <a href="http://dotnetkicks.com">DotNetKicks</a> community for their considerable support this year.  </p>
<h3>2007&#8217;s most popular posts:</h3>
<p><strong><a href="http://encosia.com/2007/07/13/easily-refresh-an-updatepanel-using-javascript/">Easily refresh an UpdatePanel, using JavaScript</a></strong>:  Even to this day, it&#8217;s one of my most viewed posts.  The __doPostBack technique is something that I&#8217;ve been dogfooding extensively since, and I can say without hesitation that it&#8217;s a great way to programmatically trigger server side events from client script.</p>
<p>I owe <a href="http://asp.net/learn/ajax-videos/video-172.aspx">Joe Stagner</a> big time for the popularity of this post.  Thank you, Joe.</p>
<p><strong><a href="http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/">Why ASP.NET AJAX UpdatePanels are dangerous</a></strong>:  This post exploded my traffic.  It seemed to really strike a nerve with a lot of people, which wasn&#8217;t my intent at all.  However, I still absolutely stand by every word of the post.  Continuing real-world experience has only served to reinforce my opinion on the matter.  Just a cursory search of the ASP.NET forums backs it up strongly as well.</p>
<p><strong><a href="http://encosia.com/2007/10/24/are-you-making-these-3-common-aspnet-ajax-mistakes/">Are you making these 3 common ASP.NET AJAX mistakes?</a></strong>:  I didn&#8217;t expect this to be a popular post.  If anything, I felt like it was rushed and not as complete as I would&#8217;ve liked.  However, it&#8217;s my third most viewed page for the year, so who am I to judge?</p>
<p><strong><a href="http://encosia.com/2007/08/23/seamless-inline-text-editing-with-aspnet-ajax/">Seamless inline text editing with ASP.NET AJAX</a></strong>:  This one, I was really proud of.  I was tired of seeing all the flashy, lightweight techniques on other platforms, while we all wallowed in UpdatePanel bloat.  So, I wanted to demo something that was heavy on the client side magic and didn&#8217;t rely on partial postbacks at all.  Goal achieved!</p>
<p>I owe <a href="http://weblogs.asp.net/scottgu/archive/2007/08/30/august-30th-links-asp-net-asp-net-ajax-iis7-visual-studio-silverlight-net.aspx">ScottGu</a> for a lot of this post&#8217;s popularity.  Thanks, Scott.</p>
<p><strong><a href="http://encosia.com/2007/07/25/display-data-updates-in-real-time-with-ajax/">Display data updates in real-time with AJAX</a></strong>:  I don&#8217;t know if it was due to a bad title or what, but this one was a bit of a sleeper.  It drew almost no interest at first, but its popularity eventually began to grow rapidly after a month or two.</p>
<p>I plan on reprising this post with a completely client side solution soon, using no partial postbacks at all.  I&#8217;ve been using that technique in production, gaining amazing performance gains of 20-80x over partial postbacks to render GridViews.</p>
<h3>Honorable mention</h2>
<p>The post that I most wish had done better than it did is <strong><a href="http://encosia.com/2007/10/03/easy-incremental-status-updates-for-long-requests/">Easy incremental status updates for long requests</a></strong>.  It&#8217;s something that I see people struggling with almost daily on the ASP.NET forums, and I wish that I could have put the post in front of more eyeballs than I did.</p>
<p>I hold out hope that it will gain popularity over time, like the real-time updates post did.  Until then, I suppose I&#8217;ll just have to keep watching the ASP.NET forums and pointing people to it when they&#8217;re in need.</p>
<h3>Contest winners</h3>
<p>Okay, I feel a bit like a news weatherman, putting the part you actually care about at the end of the post.  I know this is what you&#8217;re really interested in, so let&#8217;s get on with it.</p>
<p>Winner #1 (Comment):  <strong>Clinton Gallagher</strong></p>
<p>Winner #2 (RSS entry):  <strong>Nichole Dugan</strong></p>
<p>Winner #3 (Email list):  <strong>JStengel@*****.***</strong></p>
<p><strong>Congratulations</strong> to the winners, and check your email.  I&#8217;ll be in touch soon.</p>
<p>To those who didn&#8217;t win this time, stay tuned.  The success of this week&#8217;s contest has definitely paved the way for more in the future.</p>
<h3>Thanks to our sponsor</h3>
<p>Again, I would like to thank <a href="http://www.manning.com/" target="_blank" rel="nofollow">Manning Publications</a> and <a href="http://aspadvice.com/blogs/garbin/">Alessandro Gallo</a> for providing these books to give away.  Without them, none of this week&#8217;s fun would have been possible.</p>
<p>If you didn&#8217;t win, I hope you&#8217;ll still consider picking the book up.  It&#8217;s a great book to begin with, and you just have to love a company that supports the .NET community like this.</p>
<p>I hope you all have a safe and happy holiday, and I&#8217;ll see you back here next year!</p>
<p>Originally posted at: <a href="http://encosia.com">Encosia</a>.</p>
<div class="feedflare">
<a href="http://feeds.encosia.com/~f/Encosia?a=AcltwVc"><img src="http://feeds.encosia.com/~f/Encosia?i=AcltwVc" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=q9WyfwC"><img src="http://feeds.encosia.com/~f/Encosia?i=q9WyfwC" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=bbzdCvC"><img src="http://feeds.encosia.com/~f/Encosia?i=bbzdCvC" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=avrmApC"><img src="http://feeds.encosia.com/~f/Encosia?i=avrmApC" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=90ayu0c"><img src="http://feeds.encosia.com/~f/Encosia?i=90ayu0c" border="0"></img></a> <a href="http://feeds.encosia.com/~f/Encosia?a=oK2ftRc"><img src="http://feeds.encosia.com/~f/Encosia?i=oK2ftRc" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/2007/12/21/best-of-2007-5-most-popular-posts-and-contest-winners/feed/</wfw:commentRss>
		<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetItemData?uri=Encosia&amp;itemurl=http%3A%2F%2Fencosia.com%2F2007%2F12%2F21%2Fbest-of-2007-5-most-popular-posts-and-contest-winners%2F</feedburner:awareness></item>
	<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetFeedData?uri=Encosia</feedburner:awareness></channel>
</rss><!-- Dynamic Page Served (once) in 0.793 seconds -->
