<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Encosia &#187; AJAX</title>
	<atom:link href="http://encosia.com/category/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://encosia.com</link>
	<description>ASP.NET and AJAX code, ideas, and examples.</description>
	<lastBuildDate>Sun, 29 Apr 2012 21:35:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Using CORS to access ASP.NET services across domains</title>
		<link>http://encosia.com/using-cors-to-access-asp-net-services-across-domains/</link>
		<comments>http://encosia.com/using-cors-to-access-asp-net-services-across-domains/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 06:25:26 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1223</guid>
		<description><![CDATA[Work on client-side applications long enough and it&#8217;s just about inevitable that you&#8217;ll eventually want to make an AJAX request that breaches the browser&#8217;s XMLHttpRequest security restrictions. Limitations on cross-domain requests are great when they&#8217;re preventing malicious sites from malfeasing, but are a thorn in the side when they complicate your legitimate applications. Traditionally, direct [...]
Related posts:<ol>
<li><a href='http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/' rel='bookmark' title='Save yourself some typing when you call ASP.NET services'>Save yourself some typing when you call ASP.NET services</a></li>
<li><a href='http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/' rel='bookmark' title='ASMX and JSON &ndash; Common mistakes and misconceptions'>ASMX and JSON &ndash; Common mistakes and misconceptions</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://encosia.com/blog/wp-content/uploads/2011/12/successful-cors-request.png" alt="Successfully completing a cross-domain request to an ASMX service using CORS" title="Successful CORS request" style="border: 1px solid #ccc;" /></p>
<p>Work on client-side applications long enough and it&#8217;s just about inevitable that you&#8217;ll eventually want to make an AJAX request that breaches the browser&#8217;s XMLHttpRequest security restrictions. Limitations on cross-domain requests are great when they&#8217;re preventing malicious sites from malfeasing, but are a thorn in the side when they complicate your legitimate applications.</p>
<p>Traditionally, direct communication across the same-origin boundary required using a rickety (though clever) workaround called JSONP. JSONP is a reasonable compromise if all you need to do is make blind requests to a third-party API like Twitter, but comes up short if you need to use any HTTP verb other than GET. Of course, that&#8217;s <a href="http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx" target="_blank">a deal-breaking issue when you&#8217;re working with ASMX ScriptServices or ASPX page methods</a>.</p>
<p>Luckily, a relatively new feature has been making its way into browsers which provides a robust solution to the cross-domain AJAX problem: <strong>CORS</strong>.</p>
<p>In this post, I&#8217;m going to show you how to recognize exactly which requests are cross-origin, how to enable CORS for your ASP.NET site, and the extra configuration necessary when you&#8217;re working with ASP.NET&#8217;s JSON-enabled services.</p>
<p><em>Before we get started, I want to emphasize that this approach won’t work with any version of IE prior to IE10. If supporting older versions of IE is a requirement in your target environment, you’re stuck with something like JSONP or <a href="http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/" target="_blank">a server-side proxy</a>. This will work in any version of IE if Chrome Frame is installed and enabled by your site/server though.</em></p>
<h3>Understanding what constitutes a different “origin”</h3>
<p>When it comes to making cross-origin AJAX requests, it&#8217;s helpful to understand which requests actually are cross-origin. Of course, a request from a page served under one domain to a resource on an entirely different one definitely falls under the umbrella of cross-origin:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/12/failed-cors-request.png" width="490" style="border: 1px solid #ccc;" /></p>
<p>However, the common moniker for these requests, <em>cross-domain</em>, tends to be misleading. While a request from one domain to another is obviously cross-origin, browsers are much more picky than that.</p>
<p>For example, a request from <code>foo.domain.com</code> to <code>bar.domain.com</code> is just as much cross-origin request as one to <code>abc.com</code>. That’s not quite as intuitive as the traditional cross-domain scenario, but requires the same consideration.</p>
<p>A less obvious troublemaker is making a request from <code>localhost:8080</code> to <code>localhost:8081</code>, which XMLHttpRequest’s security restrictions will also deny you from making. That’s a particularly troublesome scenario for ASP.NET developers since Visual Studio is all too happy to help you spin up a separate services/API project almost transparently hosted at its own separate port.</p>
<p>The easiest way to determine whether a particular request will fall under the umbrella of cross origin resource sharing is to <strong>compare the portion of both addresses appearing before the first forward slash</strong>. Any difference before the first forward slash, including the port, protocol (HTTP vs. HTTPS), and sub-domain, will thwart a traditional XHR-based AJAX request.</p>
<h3>Enabling CORS for an ASP.NET site</h3>
<p>Though the conventional wisdom about cross-domain or cross-origin requests has long been JSONP or nothing, a solution called <a href="http://www.w3.org/TR/cors/" target="_blank">Cross-Origin Resource Sharing</a> has gained broad support in modern browsers over the past couple years. This standard defines a set of HTTP headers that a server can use to instruct browsers that it’s okay for certain XMLHttpRequest requests to that server to cross the same-origin boundary.</p>
<p>In the broadest case, enabling CORS for an ASP.NET site is simple. The <a href="http://enable-cors.org/" target="_blank">enable-cors.org</a> site has handy list of concise examples of how to configure a variety of servers for CORS, including IIS. For sites hosted on IIS7.0+ and Integrated Pipeline, enabling CORS is as simple as adding this to the site’s web.config:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.webserver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httpprotocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;customheaders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Access-Control-Allow-Origin&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/customheaders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httpprotocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.webserver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>That simple change gets you half way there. A regular GET request for an ASPX page&#8217;s HTML would work now, for example. Unfortunately, the Content-Type necessary for working with ASMX ScriptServices throws a new wrench in the works:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/12/almost-successful-cors-request.png" alt="A partially successful CORS request to an ASMX ScriptService" title="Almost successful CORS request" width="490" height="106" style="border: 1px solid #ccc;" /></p>
<p>As it turns out, requests to ASP.NET’s JSON-enabled endpoints require one last configuration step to allow the request to go through unimpeded.</p>
<h3>Access-Control-Allow-Headers</h3>
<p>Sending the <code>Access-Control-Allow-Origin</code> header allows basic cross-origin access, but calling ASP.NET services like ASMX ScriptServices, ASPX page methods, and WCF services with AspNetCompatibilityRequirements enabled <a href="http://encosia.com/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/" target="_blank">requires jumping through a few more hoops</a>. Namely, sending a specific Content-Type header of <code>application/json</code>.</p>
<p>One of the security precautions that the CORS specification includes is that browsers must tightly control what&#8217;s sent along with these cross-origin requests. Among the items that must be explicitly allowed: any but the most basic HTTP headers, including <code>Content-Type</code>.</p>
<p>In order for CORS requests to specify their Content-Type, your site needs to respond with one additional CORS header: <code>Access-Control-Allow-Headers</code></p>
<p>That brings the web.config modifications necessary to this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.webserver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httpprotocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;customheaders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Access-Control-Allow-Origin&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Access-Control-Allow-Headers&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/customheaders<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httpprotocol<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.webserver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>And finally, it&#8217;s possible to use the same, familiar jQuery <code>$.ajax()</code> syntax to request our service from same- and cross-domain origins alike:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/12/successful-cors-request.png" alt="A successful CORS request to an ASMX service with jQuery" title="Successful CORS request" width="490" height="170" style="border: 1px solid #ccc;" /></p>
<h3>Conclusion</h3>
<p>Even as we&#8217;re teetering at the precipice of 2012, CORS is still a fairly new feature and lacks ubiquitous support. IE10 should support CORS as fully as Chrome and Firefox already do, but the XDomainRequest implementation in earlier versions of IE does not (to my knowledge) support <code>Access-Control-Allow-Headers</code>, which makes it all but useless in this scenario.</p>
<p>If you&#8217;re comfortable leaving the comfy confines of XMLHttpRequest and jQuery&#8217;s <code>$.ajax</code>, a more cross-browser friendly solution does exist: <a href="http://easyxdm.net/wp/" target="_blank">easyXDM</a>. I haven&#8217;t personally used easyXDM beyond a bit of experimentation, but the approach it takes in older browsers is one that has been proven to be solid by similar libraries like <a href="http://socket.io/" target="_blank">Socket.IO</a>.</p>
<p>However, if you&#8217;re working in an environment where you can mandate Chrome (or Chrome Frame in IE9-) and/or Firefox as the browser of choice, CORS is an invaluable addition to your bag of tricks (I feel like I&#8217;ve typed that phrase in another post recently&#8230;). I hope this post will help you get your feet wet with this new technology which seems to get more lip service than actual usage.</p>
<h3>Get the source</h3>
<p>If you’d like to browse through a complete working example of what’s been covered in this post, take a look at the companion project at GitHub. Or, if you’d like to download the entire project and run it in Visual Studio to see it in action yourself, grab the ZIP archive.</p>
<p><a href="https://github.com/Encosia/Encosia-Samples-ASMX-CORS/tree/AsPublished" target="_blank" class="generalButton" style="width: 220px; float: left; text-align: center;">Browse on GitHub</a><a href="https://github.com/Encosia/Encosia-Samples-ASMX-CORS/zipball/AsPublished" target="_blank" class="generalButton" style="width: 220px; float: right; text-align: center;">Download the ZIP</a></p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/save-yourself-some-typing-when-you-call-asp-net-services/' rel='bookmark' title='Save yourself some typing when you call ASP.NET services'>Save yourself some typing when you call ASP.NET services</a></li>
<li><a href='http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/' rel='bookmark' title='ASMX and JSON &ndash; Common mistakes and misconceptions'>ASMX and JSON &ndash; Common mistakes and misconceptions</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/using-cors-to-access-asp-net-services-across-domains/">Using CORS to access ASP.NET services across domains</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/using-cors-to-access-asp-net-services-across-domains/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/using-cors-to-access-asp-net-services-across-domains/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>ASP.NET page methods are only as secure as you make them</title>
		<link>http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/</link>
		<comments>http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 16:47:58 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1155</guid>
		<description><![CDATA[One of the most persistent misconceptions about ASP.NET&#8217;s page methods is the notion that they have some intrinsic protection against requests that don&#8217;t originate from the page where they&#8217;re defined. Since a page method&#8217;s code resides within a page&#8217;s code-behind file, it&#8217;s intuitive to assume that those methods benefit from some form of inherent security. [...]
Related posts:<ol>
<li><a href='http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
<li><a href='http://encosia.com/why-do-aspnet-ajax-page-methods-have-to-be-static/' rel='bookmark' title='Why do ASP.NET AJAX page methods have to be static?'>Why do ASP.NET AJAX page methods have to be static?</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>One of the most persistent misconceptions about ASP.NET&#8217;s page methods is the notion that they have some intrinsic protection against requests that don&#8217;t originate from the page where they&#8217;re defined. Since a page method&#8217;s code resides within a page&#8217;s code-behind file, it&#8217;s intuitive to assume that those methods benefit from some form of inherent security.</p>
<p>Unfortunately, that is not the case.</p>
<h3>Exploiting your page&#8217;s insecurities</h3>
<p>In case it&#8217;s hard to believe these code-behind methods truly are so easily accessible, let&#8217;s take a look at a quick example. Let&#8217;s say you have a page method that returns sensitive business information, like so:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>WebMethod<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">int</span> SecretFormula<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  <span style="color: #0600FF;">return</span> <span style="color: #FF0000;">42</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Assuming that method is defined in a <code>Default.aspx</code> file&#8217;s code-behind, located in a folder named <code>TopSecret</code>, here&#8217;s a bit of jQuery you could use to request the secret formula from any page on the site:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'/TopSecret/Default.aspx/SecretFormula'</span><span style="color: #339933;">,</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'application/json'</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">'{}'</span><span style="color: #339933;">,</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>result.<span style="color: #660066;">d</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In fact, you can even make that request from a plain HTML file. In this example, I&#8217;m making the request right from a simple HTML file named <code>index.htm</code>:</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2011/09/accessing-page-method-firebug.png" rel="attachment"><img src="http://encosia.com/blog/wp-content/uploads/2011/09/accessing-page-method-firebug.png" title="Using jQuery to access the page method from outside its ASPX page." width="492" height="83" /></a></p>
<p>Not only is the request not originating from the ASPX file that contains the page method, <strong>that request wasn&#8217;t originating from an ASPX file at all!</strong></p>
<h3>Is this really a problem?</h3>
<p>You might be asking yourself if this is really a problem to begin with. After all, you aren&#8217;t very likely to write client-side code that requests sensitive data unless you actually need that data, regardless of whether you write that code on an ASPX page, HTML page, or anywhere else.</p>
<p>The trouble is, a villain could land on any of your site&#8217;s pages, open up Firebug, and start probing for weaknesses like this one. In this case, the obscurity of the exact location of the page method might lead you to a false sense of security, but <strong>if an attacker has any knowledge of your system&#8217;s architecture then the door is wide open</strong>.</p>
<p>Even more troubling, as long as an attacker uses POST requests with an <code>application/json</code> Content-Type, they could use a tool as simple as Fiddler to interrogate your site&#8217;s services remotely. A few lines of server-side code, and your competition could set up a site driven by the page method APIs on your site that you thought were private!</p>
<h3>A fixable problem</h3>
<p>Page methods aren&#8217;t indefensible against the shenanigans of external interlopers though. You can secure them with ASP.NET&#8217;s built-in authorization mechanism, just as you would any other ASPX page (or ASMX service). In fact, if you secure an ASPX page with ASP.NET authorization, page methods defined in its code-behind are automatically equally secure.</p>
<p>To deny unauthenticated access to methods in our <code>TopSecret</code> folder, <a href="http://msdn.microsoft.com/en-us/library/wce3kxhd.aspx" target="_blank">adding an authorization entry to the web.config in that folder</a> is all that&#8217;s necessary:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;authorization<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;deny</span> <span style="color: #000066;">users</span>=<span style="color: #ff0000;">&quot;?&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/authorization<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Now, an unauthenticated user trying to access the <code>SecretFormula</code> method from <code>index.htm</code> (or anywhere else, without authenticating first) is denied access:</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2011/09/secured-page-method-firebug.png" rel="attachment"><img src="http://encosia.com/blog/wp-content/uploads/2011/09/secured-page-method-firebug.png" alt="Attempting to request the same page method with jQuery after securing it." title="secured-page-method-firebug" width="492" height="83" /></a></p>
<p>Of course, there are a variety of ways to control access to these methods. You might test to see which role a user&#8217;s in and respond accordingly, or you might only need to verify some token stored in the Session. </p>
<p>Regardless of the particular mechanism, <strong>the key is to remember that none of this is automatic and that you must be mindful of regulating access to your page methods</strong>.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
<li><a href='http://encosia.com/why-do-aspnet-ajax-page-methods-have-to-be-static/' rel='bookmark' title='Why do ASP.NET AJAX page methods have to be static?'>Why do ASP.NET AJAX page methods have to be static?</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/">ASP.NET page methods are only as secure as you make them</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/asp-net-page-methods-are-only-as-secure-as-you-make-them/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Use ASP.NET&#8217;s HttpHandler to bridge the cross-domain gap</title>
		<link>http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/</link>
		<comments>http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 14:59:25 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1105</guid>
		<description><![CDATA[When you&#8217;re developing client-side applications, a problem you&#8217;ll almost inevitably have to deal with is how to work with services that reside outside your website&#8217;s domain. Though many modern APIs do support JSONP, which is a clever workaround to somewhat mitigate the cross-domain problem, JSONP has its own problems. Worse, if you encounter an API [...]
Related posts:<ol>
<li><a href='http://encosia.com/ajax-file-downloads-and-iframes/' rel='bookmark' title='AJAX, file downloads, and IFRAMEs'>AJAX, file downloads, and IFRAMEs</a></li>
<li><a href='http://encosia.com/the-easiest-way-to-break-aspnet-ajax-pages/' rel='bookmark' title='The easiest way to break ASP.NET AJAX pages'>The easiest way to break ASP.NET AJAX pages</a></li>
<li><a href='http://encosia.com/why-aspnet-ajax-updatepanels-are-dangerous/' rel='bookmark' title='Why ASP.NET AJAX UpdatePanels are dangerous'>Why ASP.NET AJAX UpdatePanels are dangerous</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re developing client-side applications, a problem you&#8217;ll almost inevitably have to deal with is how to work with services that reside outside your website&#8217;s domain. Though many modern APIs do support JSONP, which is a clever workaround to somewhat mitigate the cross-domain problem, JSONP has its own problems.</p>
<p>Worse, if you encounter an API with no JSONP support, <strong>the cross-domain barrier can quickly become a formidable one</strong>. <a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/" target="_blank">CORS</a> is slowly becoming a viable alternative, but it requires that the remote service support it via special HTTP headers and browser support for <a href="http://caniuse.com/#search=cors" target="_blank">CORS is still not ubiquitous</a>.</p>
<p>Until CORS is more broadly supported, an alternative solution is to bounce cross-domain requests through the web server that hosts your website. In ASP.NET, the best tool for implementing that sort of middleman endpoint is the <a href="http://msdn.microsoft.com/en-us/library/ms228090.aspx" target="_blank">HttpHandler</a>.</p>
<p>In this post, I’ll show you <strong>how to create an HttpHandler</strong> to service cross-domain requests, how to <strong>use jQuery to communicate with the handler</strong>, and <strong>an example of one improvement</strong> that this approach makes possible.</p>
<h3>An example remote API</h3>
<p>To focus on an example that&#8217;s already familiar to many, I&#8217;m going to use Twitter. Twitter&#8217;s API <em>does</em> support JSONP, which is a viable alternative for consuming it across domains. In fact, the Twitter status that you see in my sidebar to the right was retrieved from Twitter&#8217;s API via JSONP.</p>
<p>However, not every service supports JSONP, its third-party script injection mechanism is sometimes problematic, and using JSONP robs us of niceties like local caching. So, for the sake of a good example, let&#8217;s find a way to use the Twitter API on the client-side without resorting to JSONP.</p>
<p>Specifically, I&#8217;m interested in querying the service for my last few status updates. The Twitter API request to accomplish that looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">http://api.twitter.com/1/statuses/user_timeline.json?id=Encosia</pre></div></div>

<p>Twitter will respond to that with a JSON array of objects representing my (or your) last 20 tweets, which is exactly what we&#8217;re after.</p>
<h3>The best tool for the job: HttpHandler</h3>
<p>If you&#8217;re accustomed to using ASP.NET&#8217;s <a href="http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/" target="_blank">page methods</a> and <a href="http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/" target="_blank">ScriptServices</a> to facilitate communication between client and server, those tools begin to look like a hammer that matches every JSON-shaped nail in sight. However, when simply relaying an external API&#8217;s JSON through to the client, they often add unnecessary overhead and complexity.</p>
<p>Rather, a lower-level tool is more appropriate in this case.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.processrequest.aspx" target="_blank" rel="nofollow">HttpHandlers</a> are one of ASP.NET’s most under-utilized tools. They&#8217;re simple to implement and allow you to handle requests closer to the metal than WebForms pages or MVC controller actions.</p>
<p>One place in particular where HttpHandlers shine is where you would otherwise consider writing <code>Response.Write</code> statements in a WebForms page’s code-behind. This anti-pattern of using ASPX&#8217;s code-behind to get closer to the metal <em>looks</em> similar to approaches that you&#8217;ll see on some other platforms, such as PHP, but is not equivalent.</p>
<p>Unfortunately, even if you don&#8217;t use WebForms controls or ASPX markup at all, executing that low-level code from an ASPX page&#8217;s code-behind requires that every request filter through the full page life cycle. That means even the simplest request still has to percolate <a href="http://msdn.microsoft.com/en-us/library/ms178472.aspx#lifecycle_events" target="_blank" rel="nofollow">all the way from PreInit to Unload</a>, adding needless overhead.</p>
<p>Instead, the HttpHandler is where you should write that sort of code that ultimately boils down to <code>Response.Write</code> calls.</p>
<h3>Choosing the right handler type</h3>
<p>A tricky issue when you&#8217;re writing your first HttpHandler is that Visual Studio presents you with two templates, “ASP.NET Handler” and “Generic Handler”:</p>
<p><a href="http://encosia.com/blog/wp-content/uploads/2011/07/add-httphandler-dialog.png" rel="attachment" class="cboxElement"><img src="http://encosia.com/blog/wp-content/uploads/2011/07/add-httphandler-dialog.png" alt="The add item dialog presents two choices of HttpHandler templates" title="Add HttpHandler dialog" width="492" height="330" /></a></p>
<p>Both are similar, but the “ASP.NET Handler” template’s approach requires modifying your web.config to configure which URL your handler accepts requests at. Mucking around in the web.config isn&#8217;t terribly difficult, but it’s extra friction which makes the process less approachable.</p>
<p>In the spirit of keeping things simple, let&#8217;s stick with the more traditionally file-based “Generic Handler”.</p>
<h3>Getting started with your first HttpHandler</h3>
<p>After choosing that template, specifying a name, and adding the new file to your site, you’ll end up with a bit of boilerplate code that includes this method:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ProcessRequest<span style="color: #000000;">&#40;</span>HttpContext context<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;text/plain&quot;</span><span style="color: #008000;">;</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Hello World&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>If you start the site up in Visual Studio and then request your newly-created HttpHandler in a browser, <code>Handler1.ashx</code> if you accept the default name, you will see “Hello World” as you might expect.</p>
<p>That&#8217;s not very impressive yet, but the response you saw made its way to your browser without touching WebForms’ page life cycle or filtering through ASP.NET MVC’s routing engine and action filters. While those things are worthwhile niceties for the majority of your application, they’re unwanted overhead when all you need is to efficiently relay some content through the server.</p>
<h3>Bouncing a request to Twitter through the HttpHandler</h3>
<p>To adapt an HttpHandler for relaying requests to the Twitter API, we can use <a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx" target="_blank" rel="nofollow">.NET&#8217;s handy WebClient class</a> to make the request to Twitter&#8217;s API, and then return the result back through as the handler&#8217;s response:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ProcessRequest<span style="color: #000000;">&#40;</span>HttpContext context<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  WebClient twitter <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WebClient<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// The base URL for Twitter API requests.</span>
  <span style="color: #FF0000;">string</span> baseUrl <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;http://api.twitter.com/1/&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// The specific API call that we're interested in.</span>
  <span style="color: #FF0000;">string</span> request <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;statuses/user_timeline.json?id=Encosia&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Make a request to the API and capture its result.</span>
  <span style="color: #FF0000;">string</span> response <span style="color: #008000;">=</span> twitter.<span style="color: #0000FF;">DownloadString</span><span style="color: #000000;">&#40;</span>baseUrl <span style="color: #008000;">+</span> request<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Set the content-type so that libraries like jQuery can </span>
  <span style="color: #008080; font-style: italic;">//  automatically parse the result.</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;application/json&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Relay the API response back down to the client.</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>response<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>That code simply makes an HTTP request to the Twitter API and blindly bounces the result back through as the HttpHandler&#8217;s response. For the time being, everything is hard-coded, but we&#8217;ll improve on that soon enough.</p>
<h4>Using the handler proxy on the client-side</h4>
<p>With our web server doing the heavy lifting, using this server-side proxy to make a remote request is trivial:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">getJSON</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'TwitterProxy.ashx'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tweets<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Call a magical function that does all the presentational work.</span>
  displayTweets<span style="color: #009900;">&#40;</span>tweets<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The jQuery code here is actually identical what you&#8217;d use when requesting the API via JSONP. Whether that response is truly being fulfilled by the specified URL or it&#8217;s being relayed through our HttpHandler, <strong>it&#8217;s all the same to the jQuery code on the client-side</strong>.</p>
<p>As you&#8217;ll see when we add caching, this can easily be exploited for good.</p>
<h3>Mixing things up with QueryString parameters</h3>
<p>The hard-coded approach works well enough, but what if we wanted to be able to query any Twitter account&#8217;s recent updates instead of being limited to just <a href="https://twitter.com/encosia" target="_blank">that boring Encosia character</a>?</p>
<p>Since HttpHandlers receive an instance of the current HttpContext as the parameter to their ProcessRequest method, it&#8217;s easy to access QueryString parameters and react accordingly. For example, this would allow us to request any Twitter account&#8217;s timeline by via an <code>id</code> parameter on the QueryString:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ProcessRequest<span style="color: #000000;">&#40;</span>HttpContext context<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  WebClient twitter <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WebClient<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #FF0000;">string</span> baseUrl <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;http://api.twitter.com/1/&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Extract the desired account ID from the QueryString.</span>
  <span style="color: #FF0000;">string</span> id <span style="color: #008000;">=</span> context.<span style="color: #0000FF;">Request</span>.<span style="color: #0000FF;">QueryString</span><span style="color: #000000;">&#91;</span><span style="color: #666666;">&quot;id&quot;</span><span style="color: #000000;">&#93;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Make a request to the API for the specified id.</span>
  <span style="color: #FF0000;">string</span> request <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;statuses/user_timeline.json?id=&quot;</span> <span style="color: #008000;">+</span> id<span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Same as before, from here on out:</span>
  <span style="color: #FF0000;">string</span> response <span style="color: #008000;">=</span> twitter.<span style="color: #0000FF;">DownloadString</span><span style="color: #000000;">&#40;</span>baseUrl <span style="color: #008000;">+</span> request<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;application/json&quot;</span><span style="color: #008000;">;</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>response<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Now it works exactly the same way as before, but we can choose which Twitter account&#8217;s timeline is requested. For example, this URL would request <a href="http://weblogs.asp.net/scottgu/" target="_blank">Scott Guthrie</a>&#8216;s latest tweets:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">TwitterProxy.ashx?id=ScottGu</pre></div></div>

<h4>Supplying parameters with $.getJSON</h4>
<p>To pass this new parameter in from the client-side, you could handcraft the entire URL including the appropriate QueryString. Even better though, <code>$.getJSON</code> has <a href="http://api.jquery.com/jQuery.getJSON/" target="_blank">an optional &#8220;data&#8221; argument</a> that accepts a JavaScript object and converts it to QueryString parameters:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">getJSON</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'TwitterProxy.ashx'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> id<span style="color: #339933;">:</span> <span style="color: #3366CC;">'ScottGu'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tweets<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  displayTweets<span style="color: #009900;">&#40;</span>tweets<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>jQuery will automatically URLEncode the parameters you specify in the &#8220;data&#8221; argument and properly assemble them into the final URL to be requested:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/08/request-in-firebug.png" alt="Screenshot of the HttpHandler request generated by the jQuery code above." title="HttpHandler request in Firebug" width="490" height="145" style="border: 1px solid #333;" /></p>
<p>Which is exactly what we need it to do.</p>
<p>Using a configuration object like this is cleaner than manually concatenating a string together and makes it easier to vary the parameter at runtime.</p>
<h3>Improving performance with server-side caching</h3>
<p>An advantage the HttpHandler proxy has over CORS and JSONP is that you can perform any arbitrary server-side processing that you wish, both before and after the remote service repsonds. <strong>A great way to take advantage of that is adding a server-side caching layer</strong>. </p>
<p>Server-side caching will reduce how often requests actually trigger API calls and can significantly improve performance for requests that are already cached. A caching middleman like this is especially valuable when dealing with rate-limited APIs like Twitter&#8217;s.</p>
<p>Let&#8217;s say that we wanted to cache Twitter responses for up to five minutes, for example:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ProcessRequest<span style="color: #000000;">&#40;</span>HttpContext context<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">// This will be the case whether there's a cache hit or not.</span>
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">ContentType</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;application/json&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Check to see if the twitter status is already cached,</span>
  <span style="color: #008080; font-style: italic;">//   then retrieve and return the cached value if so.</span>
  <span style="color: #008080; font-style: italic;">// 8/3/11: Updated with more robust test, thanks to ctolkien.</span>
  <span style="color: #FF0000;">object</span> tweetsCache <span style="color: #008000;">=</span> context.<span style="color: #0000FF;">Cache</span><span style="color: #000000;">&#91;</span><span style="color: #666666;">&quot;tweets-&quot;</span> <span style="color: #008000;">+</span> id<span style="color: #000000;">&#93;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>tweetsCache <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #FF0000;">string</span> cachedTweets <span style="color: #008000;">=</span> tweetsCache.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>cachedTweets<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// We're done here.</span>
    return<span style="color: #008000;">;</span>
  <span style="color: #000000;">&#125;</span>
&nbsp;
  WebClient twitter <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> WebClient<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// Move along; nothing to see here. The concatenation is just</span>
  <span style="color: #008080; font-style: italic;">//  to avoid horizontal scrolling within the meager 492</span>
  <span style="color: #008080; font-style: italic;">//  pixels I have to work with here.</span>
  <span style="color: #FF0000;">string</span> url <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;http://api.twitter.com/1/statuses/&quot;</span> <span style="color: #008000;">+</span>
               <span style="color: #666666;">&quot;user_timeline.json?id=Encosia&quot;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #FF0000;">string</span> tweets <span style="color: #008000;">=</span> twitter.<span style="color: #0000FF;">DownloadString</span><span style="color: #000000;">&#40;</span>url<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">// This monstrosity essentially just caches the WebClient result</span>
  <span style="color: #008080; font-style: italic;">//  with a maximum lifetime of 5 minutes from now.</span>
  <span style="color: #008080; font-style: italic;">// If you don't care about the expiration, this can be a simple</span>
  <span style="color: #008080; font-style: italic;">//  context.Cache[&quot;tweets&quot;] = tweets; instead.</span>
  context.<span style="color: #0000FF;">Cache</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;tweets&quot;</span>, tweets,
    <span style="color: #0600FF;">null</span>, DateTime.<span style="color: #0000FF;">Now</span>.<span style="color: #0000FF;">AddMinutes</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">5</span><span style="color: #000000;">&#41;</span>, 
    <span style="color: #000000;">System.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Caching</span></span>.<span style="color: #0000FF;">Cache</span>.<span style="color: #0000FF;">NoSlidingExpiration</span>,
    <span style="color: #000000;">System.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Caching</span></span>.<span style="color: #0000FF;">CacheItemPriority</span>.<span style="color: #0000FF;">Normal</span>, 
    <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  context.<span style="color: #0000FF;">Response</span>.<span style="color: #0000FF;">Write</span><span style="color: #000000;">&#40;</span>tweets<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Adding the intermediate cache results in a tremendous performance improvement after the first request:</p>
<p><img src="http://encosia.com/blog/wp-content/uploads/2011/08/cached-twitter-requests.png" style="border: 1px solid #333;" width="490" height="134" alt="Screenshot of an initial uncached request to Twitter and then the subsequent, cached requests" /></p>
<p>With the server able to immediately serve requests within the five minute caching window, subsequent $.getJSON requests are an order of magnitude faster!</p>
<p>Perhaps even more importantly in the case of Twitter, these four refreshes only counted as one API call against my hourly rate-limit.</p>
<h3>Conclusion</h3>
<p>Using HttpHandlers as server-side proxies turns out to be a simple way to solve the pesky cross-domain restrictions that we&#8217;ve all run into from time to time. All said and done, using an HttpHandler to proxy third-party requests takes few lines of code, but offers nearly unlimited flexibility.</p>
<p>In addition to the obvious benefit of getting around the cross-domain restriction, bouncing requests through your own server potentially has a range of other benefits, including:</p>
<ul>
<li><strong>Error handling</strong> &#8211; This approach not only passes unhandled exceptions on the WebClient request back through to the client-side, but it also gives you the ability to enhance the error handling with your own sanity checks and constraints.</li>
<li><strong>Caching</strong> &#8211; As shown in this post&#8217;s final example, you can very easily interject your own caching layer for requests passing through the HttpHandler proxy. That&#8217;s especially useful when working against rate limited or potentially slow/flaky APIs (like Twitter&#8217;s).</li>
<li><strong>Security</strong> &#8211; When you&#8217;re accustomed to server-side programming, the revealing nature of client-side JavaScript can be unnerving. Learning to appropriately partition sensitive algorithms and data between client and server is key to mitigating that issue. Along those lines, moving the remote request to code running on your server is one way to keep sensitive information like API keys and passwords safely hidden from view-source and client-side developer tools.</li>
<li><strong>Reliability</strong> &#8211; One of JSONP&#8217;s less obvious drawbacks is the fact that it relies on injecting a third-party script. However, your users may be using something like NoScript to purposely block third-party scripts, effectively shutting down your ability to use JSONP. Even if you prefer JSONP in most cases, a local server-side proxy can be helpful as a fallback in case of unexpected JSONP failures.</li>
</ul>
<p>That&#8217;s not to say that there&#8217;s no downsides to this approach. When you&#8217;re using an HttpHandler proxy, it&#8217;s important to keep in mind that it can be slower since you&#8217;re making a series of two connections instead of a single, direct one. You also lose the ability to request content with the user&#8217;s third-party cookies attached to the request, which is helpful in some cases.</p>
<p>Overall, using server-side proxies is a very useful item to have in your toolbox. I hope this post has served to introduce you to the approach and/or given you better insight into how you can use HttpHandlers to your advantage.</p>
<h3>Get the source</h3>
<p>If you&#8217;d like to browse through a complete working example of what&#8217;s been covered in this post, take a look at the companion project at GitHub. Or, if you&#8217;d like to download the entire project and run it in Visual Studio to see it in action yourself, grab the ZIP archive.</p>
<p><a href="https://github.com/Encosia/Encosia-Samples-HttpHandler-Proxy/tree/AsPublished" target="_blank" class="generalButton" style="width: 220px; float: left; text-align: center;">HttpHandler-Proxy on GitHub</a><a href="https://github.com/Encosia/Encosia-Samples-HttpHandler-Proxy/zipball/AsPublished" target="_blank" class="generalButton" style="width: 220px; float: right; text-align: center;">HttpHandler-Proxy.zip</a></p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/ajax-file-downloads-and-iframes/' rel='bookmark' title='AJAX, file downloads, and IFRAMEs'>AJAX, file downloads, and IFRAMEs</a></li>
<li><a href='http://encosia.com/the-easiest-way-to-break-aspnet-ajax-pages/' rel='bookmark' title='The easiest way to break ASP.NET AJAX pages'>The easiest way to break ASP.NET AJAX pages</a></li>
<li><a href='http://encosia.com/why-aspnet-ajax-updatepanels-are-dangerous/' rel='bookmark' title='Why ASP.NET AJAX UpdatePanels are dangerous'>Why ASP.NET AJAX UpdatePanels are dangerous</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/">Use ASP.NET&#8217;s HttpHandler to bridge the cross-domain gap</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/use-asp-nets-httphandler-to-bridge-the-cross-domain-gap/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well</title>
		<link>http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/</link>
		<comments>http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 16:24:57 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1086</guid>
		<description><![CDATA[jQuery 1.5&#8242;s complete overhaul of the AJAX API has led to several people contacting me recently, understandably nervous about how the rewrite will impact working with ASMX ScriptServices and ASPX page methods. Seeing the default calling syntax change to $.ajax(url, settings) was especially unsettling to many. I&#8217;m happy to report that the short answer is: [...]
Related posts:<ol>
<li><a href='http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>jQuery 1.5&#8242;s complete overhaul of the AJAX API has led to several people contacting me recently, understandably nervous about how the rewrite will impact working with ASMX ScriptServices and ASPX page methods.  Seeing the default calling syntax change to <code>$.ajax(url, settings)</code> was especially unsettling to many.</p>
<p>I&#8217;m happy to report that the short answer is: <strong>jQuery 1.5&#8242;s new AJAX module has almost no negative impact on any of the techniques you may have read about here</strong>.  The rewrite maintains very good compatibility for the <code>$.ajax(settings)</code> calling syntax and for now-deprecated features such as dataFilters.</p>
<p>One advanced dataFilter usage appears to be broken, but it&#8217;s something that you probably already stopped using with jQuery 1.4. To be clear, I&#8217;ll briefly enumerate all of the techniques I&#8217;ve re-tested and jQuery 1.5&#8242;s impact (or lack thereof) on each.</p>
<h3>ASMX ScriptServices and ASPX page methods</h3>
<p>The most common way of using jQuery to communicate with an ASP.NET WebForms application today is to use an ASMX ScriptService or ASPX page method. If you&#8217;re <a href="http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/">requesting an ASMX ScriptService using the approach I originally described</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json&quot;</span><span style="color: #339933;">,</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/YourService.asmx/YourMethod&quot;</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;{}&quot;</span><span style="color: #339933;">,</span>
  dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;json&quot;</span><span style="color: #339933;">,</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>msg.<span style="color: #660066;">d</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That code will continue to work exactly as-is with jQuery 1.5. If you prefer <a href="http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/">page methods</a> instead, you&#8217;re in the clear too.</p>
<p><em>Note: You can simplify the contentType parameter to &#8220;application/json&#8221; when using any version. The ScriptService handler only checks that the header contains &#8220;application/json&#8221;, not for an exact string match. It&#8217;s a small improvement, but noticeably easier to remember and type.</em> </p>
<h3>DTOs and JSON.stringify()</h3>
<p>If you&#8217;re using jQuery and ASP.NET JSON endpoints to accomplish more complicated tasks, you may be <a href="http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/">using JSON.stringify() to simplify making requests that include data transfer objects</a>. Paired with corresponding complex types or collections on the server-side, this approach seems almost too good to be true:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> NewPerson <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
NewPerson.<span style="color: #660066;">FirstName</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#FirstName&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">LastName</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#LastName&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">Address</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#Address&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">City</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#City&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">State</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#State&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
NewPerson.<span style="color: #660066;">Zip</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#Zip&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> DTO <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">'Person'</span> <span style="color: #339933;">:</span> NewPerson <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json; charset=utf-8&quot;</span><span style="color: #339933;">,</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;PersonService.asmx/AddPerson&quot;</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> JSON.<span style="color: #660066;">stringify</span><span style="color: #009900;">&#40;</span>DTO<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;json&quot;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>jQuery 1.5&#8242;s AJAX rewrite has not impacted that technique either.  If you provide a string value for its <code>data</code> parameter, jQuery will pass that string on to the server unmodified.</p>
<h3>dataFilters and &#8220;.d&#8221;</h3>
<p>With jQuery 1.5 fundamentally revamping <code>$.ajax()</code>&#8216;s extensibility model, the technique of <a href="http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/">using a dataFilter to normalize ASP.NET&#8217;s &#8220;.d&#8221; wrapper</a> is what I worried most about surviving the 1.5 transition. That approach looked like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajaxSetup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json; charset=utf-8&quot;</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;{}&quot;</span><span style="color: #339933;">,</span>
  dataFilter<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>msg.<span style="color: #660066;">hasOwnProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'d'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">return</span> msg.<span style="color: #660066;">d</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">else</span>
      <span style="color: #000066; font-weight: bold;">return</span> msg<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'YourService.asmx/YourMethod'</span><span style="color: #339933;">,</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// You'll never have to worry about the response being </span>
    <span style="color: #006600; font-style: italic;">//  buried in response.d here.</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Though jQuery 1.5&#8242;s new <a href="http://api.jquery.com/extending-ajax/#Converters">converters</a> will probably enable a better solution, this dataFilter approach does continue to work in jQuery 1.5.</p>
<h3>dataFilters and JSON parsing</h3>
<p>While the simple dataFilter does work, if you&#8217;re <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/">using a dataFilter to implement custom JSON parsing</a>, you may need to make a small change.  What I mean by that is code like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Your usual $.ajax() URL, data, dataType, etc.</span>
  dataFilter<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #009900;">&#40;</span>JSON<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #3366CC;">'undefined'</span> <span style="color: #339933;">&amp;&amp;</span> 
        <span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #009900;">&#40;</span>JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">return</span> JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">else</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'('</span> <span style="color: #339933;">+</span> data <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The usefulness of that approach dates back to jQuery 1.3 and earlier, when jQuery exclusively used <code>eval()</code> for deserializing JSON responses.  At that time, it was helpful to manually override the deserialization process to take advantage of browser-native implementations of <code>JSON.parse()</code> when available.  Doing so yielded both performance and security gains.</p>
<p>In jQuery 1.4, this was no longer necessary because jQuery contained a similar bit of browser-native parser testing code itself.  However, the dataFilter approach above did continue to work in jQuery 1.4 $.ajax() requests, so long as the dataType for the request was either omitted or set to a value that didn&#8217;t trigger jQuery&#8217;s automatic JSON deserialization (e.g. &#8220;text&#8221; or &#8220;foo&#8221;).</p>
<p>As of jQuery 1.5, <strong>using this dataFilter approach for manually controlling deserialization will no longer work if the request&#8217;s dataType is set to &#8220;json&#8221; or even omitted</strong>.</p>
<p>Except for the most obscure of edge cases, the best solution is simply to drop this code.  It&#8217;s redundant if you&#8217;re using jQuery 1.4.0 or later.  Again though, you <em>can</em> continue using a dataFilter to handle the &#8220;.d&#8221; issue.</p>
<h3>Conclusion</h3>
<p>For the most part, upgrading to jQuery 1.5 is a non-issue when it comes to using <code>$.ajax()</code> with ASP.NET JSON endpoints. Considering the fundamental nature of the module&#8217;s rewrite, it really is commendable how well backwards compatibility has been maintained.</p>
<p>Once you&#8217;ve vetted your existing code for compatibility with jQuery 1.5, do be sure to check out the powerful new features that have been added to <code>$.ajax()</code> in this rewrite.  Its new extension points, <a href="http://api.jquery.com/extending-ajax/#Prefilters">prefilters</a>, <a href="http://api.jquery.com/extending-ajax/#Converters">converters</a>, and <a href="http://api.jquery.com/extending-ajax/#Transports">transports</a>, will offer finer-grained control than ever before.</p>
<p>Even more exciting is the AJAX rewrite&#8217;s inclusion of &#8220;deferreds&#8221;.  You can count on seeing more about that here soon, but right now I highly recommend taking a look at <a href="http://www.erichynds.com/jquery/using-deferreds-in-jquery/">this post by Eric Hynds</a>.</p>
<p>If you&#8217;ve tested jQuery 1.5 in your own sites/projects, I&#8217;m curious if you&#8217;ve run into any issues I didn&#8217;t address.  Please do leave a comment if I&#8217;ve missed anything that caused you trouble in the upgrade.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/">jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Understanding jQuery&#8217;s impact on Microsoft and ASP.NET</title>
		<link>http://encosia.com/understanding-jquerys-impact-on-microsoft-and-asp-net/</link>
		<comments>http://encosia.com/understanding-jquerys-impact-on-microsoft-and-asp-net/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 17:49:45 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=1052</guid>
		<description><![CDATA[It hasn’t been easy keeping up with the twists and turns that Microsoft’s client-side frameworks and libraries have taken in the past couple years. Even today, I still hear from a surprising number of developers that don’t realize the ASP.NET Ajax Library is dead. With that in mind, I’ve been writing an article on and [...]
Related posts:<ol>
<li><a href='http://encosia.com/what-aspnet-developers-should-know-about-jquery/' rel='bookmark' title='What ASP.NET developers should know about jQuery'>What ASP.NET developers should know about jQuery</a></li>
<li><a href='http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/' rel='bookmark' title='How you can force the Ajax Script Loader to use jQuery 1.4'>How you can force the Ajax Script Loader to use jQuery 1.4</a></li>
<li><a href='http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>It hasn’t been easy keeping up with the twists and turns that Microsoft’s client-side frameworks and libraries have taken in the past couple years. Even today, I still hear from a surprising number of developers that don’t realize the ASP.NET Ajax Library is dead.</p>
<p>With that in mind, I’ve been writing an article on and off for the past several months that attempts to disambiguate Microsoft’s various client-side initiatives and hopefully provide some clarity. When Karsten from Mix Online contacted me about writing another article for them, we decided that this would be a perfect follow up to <a href="http://visitmix.com/Articles/What-ASPNET-Developers-Should-Know-About-jQuery" target="_blank">the jQuery article I wrote for them last year</a>.</p>
<p>Here’s the first few paragraphs:</p>
<blockquote>
<p>When Microsoft announced they would begin providing official support for jQuery, few of us realized how profoundly that announcement would eventually impact client-side development on the ASP.NET platform. Since that announcement, using jQuery with ASP.NET has moved from the obscure, to a central role in ASP.NET MVC’s client-side story, and now to the point of potentially superseding ASP.NET AJAX itself.</p>
<p>The journey hasn’t been all smooth. With Microsoft’s move toward jQuery, the ASP.NET AJAX, Microsoft Ajax Library, ASP.NET Ajax Library and Ajax Control Toolkit roadmaps have been uncertain at times. This has made it difficult to keep track of which projects are still relevant, and especially which you should choose going forward.</p>
<p>In my last article for Mix Online, I discussed what ASP.NET needed to know about jQuery from development perspective. In this article, I want to provide clarity on the events that led us to this point, talk about what portions of the current AJAX framework are and aren’t affected by recent changes and show you where we’re headed next. In addition, I’ll dive into the implications of the recent announcement about the adoption of Microsoft’s template library by the jQuery core.</p>
</blockquote>
<p><a href="http://visitmix.com/writings/javascript-libraries-and-asp-net-a-guide-to-jquery-ajax-and-microsoft" class="more-link">Click here to read the rest of this article at Mix Online</a></p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/what-aspnet-developers-should-know-about-jquery/' rel='bookmark' title='What ASP.NET developers should know about jQuery'>What ASP.NET developers should know about jQuery</a></li>
<li><a href='http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/' rel='bookmark' title='How you can force the Ajax Script Loader to use jQuery 1.4'>How you can force the Ajax Script Loader to use jQuery 1.4</a></li>
<li><a href='http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/understanding-jquerys-impact-on-microsoft-and-asp-net/">Understanding jQuery&#8217;s impact on Microsoft and ASP.NET</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/understanding-jquerys-impact-on-microsoft-and-asp-net/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/understanding-jquerys-impact-on-microsoft-and-asp-net/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>ASMX ScriptService mistake &#8211; Invalid JSON primitive</title>
		<link>http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/</link>
		<comments>http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 04:33:58 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASMX Mistakes and Misconceptions]]></category>
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=998</guid>
		<description><![CDATA[One group of searches that consistently brings traffic here is variations on the error: Invalid JSON primitive. Unfortunately, the post that Google sends that traffic to doesn’t address the issue until somewhere within its 150+ comments. Today, the topic gets its own post. If you’ve worked with ASMX ScriptServices or Page Methods without ASP.NET AJAX&#8217;s [...]
Related posts:<ol>
<li><a href='http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/' rel='bookmark' title='ASMX ScriptService mistake: Installation and configuration'>ASMX ScriptService mistake: Installation and configuration</a></li>
<li><a href='http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/' rel='bookmark' title='ASMX and JSON &ndash; Common mistakes and misconceptions'>ASMX and JSON &ndash; Common mistakes and misconceptions</a></li>
<li><a href='http://encosia.com/asp-net-web-services-mistake-manual-json-serialization/' rel='bookmark' title='ASP.NET web services mistake: manual JSON serialization'>ASP.NET web services mistake: manual JSON serialization</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>One group of searches that consistently brings traffic here is variations on the error: <strong>Invalid JSON primitive</strong>. Unfortunately, the post that Google sends that traffic to doesn’t address the issue until somewhere within its 150+ comments.</p>
<p>Today, the topic gets its own post.</p>
<p>If you’ve worked with ASMX ScriptServices or Page Methods without ASP.NET AJAX&#8217;s client-side proxy (e.g. using jQuery or pure XMLHttpRequest code), you’ve may have seen this cryptic error yourself. Or, perhaps you’ve just arrived here due to seeing it for the first time.</p>
<p>Either way, you may be surprised to learn that <strong>the most common reason for this error is that you’ve lied to ASP.NET</strong> during your AJAX request.</p>
<h3>It all begins with the Content-Type</h3>
<p>HTTP’s <a href="http://www.w3.org/Protocols/rfc1341/4_Content-Type.html" rel="nofollow" target="_blank">Content-Type</a> header is a fundamental aspect of communication between browsers and servers, yet often remains hidden from us in day-to-day development. <strong>The Content-Type header allows an HTTP connection to describe the format of its contents</strong>, using <a href="http://en.wikipedia.org/wiki/Internet_media_type" rel="nofollow" target="_blank">Internet media types</a> (also known as MIME types). A few common ones that you&#8217;ve probably seen before are <em>text/html</em>, <em>image/png</em>, and the more topical <em>application/json</em>.</p>
<p>Without the flexible negotiation process content types provide, your users’ browsers and your version of IIS would have to both be “ASMX Compatible” and “JSON Compatible” in order for ScriptServices to function. What a nightmare that would be! The IE6 difficulties we face today would pale in comparison.</p>
<p>Further, Content-Type negotiation is part of what allows a single URL, such as WebService.asmx, to represent data in more than one format (e.g. XML and JSON in ASMX’s case).</p>
<p>The benefits of Content-Type negotiation are well worth a bit of occasional hassle.</p>
<h3>Okay, but why does that matter?</h3>
<p>When your browser sends a POST request, the W3C&#8217;s recommendation is that it should default to using a Content-Type of <em>application/x-www-form-urlencoded</em>. <a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1" rel="nofollow" target="_blank">The HTML 4.01 spec describes that serialization scheme</a>:</p>
<blockquote>
<p>This is the default content type. Forms submitted with this content type must be encoded as follows:</p>
<ol>
<li>[Omitted for brevity; not relevant to this post.] </li>
<li>The control names/values are listed in the order they appear in the document. <strong>The name is separated from the value by &#8216;=&#8217; and name/value pairs are separated from each other by &#8216;&amp;&#8217;.</strong> </li>
</ol>
</blockquote>
<p>For an example of what that means, consider this simple form:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;form</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label&gt;</span></span>First Name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;FirstName&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Dave&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;FirstName&quot;</span> <span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;label&gt;</span></span>Last Name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/label&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;LastName&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Ward&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;LastName&quot;</span> <span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/form&gt;</span></span></pre></div></div>

<p>When the preceding form is submitted with URL encoded serialization, the request’s POST data will look like this:</p>
<p><img title="URLEncoded POST data" alt="Firebug screenshot showing the URLEncoded POST data" src="http://encosia.com/blog/wp-content/uploads/2010/05/url-encoded-post-data.png" width="492" height="172" /></p>
<p>That standardized serialization format allows a server-side backend like ASP.NET to decipher a form submission’s contents and give you access to each key/value pair. Regardless of what sort of browser submits a form to the server, the Content-Type facilitates a predictable conversion from POST data to server-side collection.</p>
<p>In other words, <strong>the Content-Type corresponds to a serialization scheme</strong>.</p>
<h3>What does that have to do with JSON Primitives?</h3>
<p>Understanding Content-Type negotiation and how it relates to serialization is important due to its role in coaxing JSON out of ASMX ScriptServices. Specifically, the fact that <a href="http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/" target="_blank">you must set a Content-Type of application/json on the request</a><em></em> means <strong>you’re instructing ASP.NET to interpret your input parameters as JSON serialized data</strong>.</p>
<p>However, the W3C&#8217;s mandate of URL encoding by default means that most AJAX libraries default to that serialization scheme. Similarly, AJAX tutorials targeting endpoints other than ASMX ScriptServices (including even ASP.NET MVC examples) will describe sending URL encoded data to the server.</p>
<p>In other words, when you’re working with a client-side object like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Person <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> FirstName<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Dave'</span><span style="color: #339933;">,</span> 
               LastName<span style="color: #339933;">:</span>  <span style="color: #3366CC;">'Ward'</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The default serialization scheme makes it easy to inadvertently transmit that data to the server as a URL encoded string:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">FirstName<span style="color: #339933;">=</span>Dave<span style="color: #339933;">&amp;</span>LastName<span style="color: #339933;">=</span>Ward</pre></div></div>

<p>Again, remember that <a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx">a Content-Type of <em>application/json</em> is a requirement when working with ASMX ScriptServices</a>. By setting that Content-Type on the request, you’ve committed to sending JSON serialized parameters, and a URL encoded string is far from valid JSON.</p>
<p>In fact, it’s <strong>invalid JSON</strong> (primitive?), hence the cryptic error message.</p>
<p>Instead of the URL encoded string above, you must be sure to send a JSON string:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'FirstName'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'Dave'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'LastName'</span><span style="color: #339933;">:</span><span style="color: #3366CC;">'Ward'</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Whether you&#8217;re using XMLHttpRequest directly or a JavaScript library that abstracts the details, getting your request&#8217;s serialization wrong is the root of the invalid JSON primitive error. However, a more specific issue tends to be the leading cause of this happening.</p>
<h3>When good JavaScript libraries go bad</h3>
<p>The most common source of this error stems from a subtlety of using jQuery’s $.ajax() method to call ASMX ScriptServices. Cobbling together snippets of code from the documentation, platform agnostic tutorials, and even posts here on my site, it’s easy to end up with something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// WRONG!</span>
$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'application/json'</span><span style="color: #339933;">,</span>
  dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'json'</span><span style="color: #339933;">,</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'WebService.asmx/Hello'</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> FirstName<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Dave&quot;</span><span style="color: #339933;">,</span> LastName<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Ward&quot;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Notice the JavaScript object literal being supplied to $.ajax()’s data parameter. That appears vaguely correct, but will result in the invalid JSON primitive error.</p>
<p>Why? <strong>jQuery serializes $.ajax()’s data parameter using the URL encoded scheme, regardless of what Content-Type is specified</strong>. Even though the contentType parameter clearly specifies JSON serialization, this URL encoded string is what jQuery will send to the server:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">FirstName<span style="color: #339933;">=</span>Dave<span style="color: #339933;">&amp;</span>LastName<span style="color: #339933;">=</span>Ward</pre></div></div>

<p>That obviously isn&#8217;t valid JSON!</p>
<p>The solution is as simple as two single-quotes:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// RIGHT</span>
$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'application/json'</span><span style="color: #339933;">,</span>
  dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'json'</span><span style="color: #339933;">,</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'WebService.asmx/Hello'</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">'{ FirstName: &quot;Dave&quot;, LastName: &quot;Ward&quot; }'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Did you spot the difference?</p>
<p>Instead of a JavaScript object literal, <strong>the data parameter is a JSON string now</strong>. <a href="http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/" target="_blank">The difference is subtle, but helpful to understand</a>. Since it’s a string, jQuery won’t attempt to perform any further transformation, and the JSON string will be unimpeded as it is passed to the ASMX ScriptService.</p>
<h3>It doesn’t have to be this way</h3>
<p>The problem is trivial once you’re aware of the underlying issue, but there’s not a great reason I can see why things need to be this way in the first place. Either half of this equation could easily provide a remedy.</p>
<p><strong>jQuery</strong> – I believe the most correct solution would be $.ajax() attempting to honor the serialization scheme indicated by its contentType parameter. In the case of <em>application/json</em>, fixing this could be easy as testing for JSON.stringify and using it if available.  That would work great, but also avoid adding any complexity/size to jQuery core.</p>
<p>That would leave it our responsibility to reference a copy of json2.js in older browsers, but that convention wouldn’t be much of a burden. <a href="http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/" target="_blank">We generally do that anyway when the client-side objects get complex</a>.</p>
<p><strong>Microsoft</strong> – It’s absolutely correct that the framework throws an error when you lie to it about what you’re sending. However, a bit of leniency could potentially save thousands of hours spent troubleshooting this problem (if my search traffic is any indication of its prevalence).</p>
<p>Is there any reason that the ScriptHandlerFactory can’t intelligently differentiate between between JSON and URL encoded inputs? If the first non-whitespace character of the request isn’t an opening curly brace, why not attempt to deserialize it as URL encoded before throwing an invalid JSON primitive error?</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/' rel='bookmark' title='ASMX ScriptService mistake: Installation and configuration'>ASMX ScriptService mistake: Installation and configuration</a></li>
<li><a href='http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/' rel='bookmark' title='ASMX and JSON &ndash; Common mistakes and misconceptions'>ASMX and JSON &ndash; Common mistakes and misconceptions</a></li>
<li><a href='http://encosia.com/asp-net-web-services-mistake-manual-json-serialization/' rel='bookmark' title='ASP.NET web services mistake: manual JSON serialization'>ASP.NET web services mistake: manual JSON serialization</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/">ASMX ScriptService mistake &#8211; Invalid JSON primitive</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>ASMX ScriptService mistake: Installation and configuration</title>
		<link>http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/</link>
		<comments>http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 03:29:07 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASMX Mistakes and Misconceptions]]></category>
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=972</guid>
		<description><![CDATA[Continuing my series of posts about ASMX services and JSON, in this post I’m going to cover two common mistakes that plague the process of getting a project’s first ASMX ScriptService working: Installing System.Web.Extensions into the GAC and configuring your web.config. System.Web.Extensions (aka ASP.NET AJAX) The ability for ASMX services to return raw JSON is [...]
Related posts:<ol>
<li><a href='http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/' rel='bookmark' title='ASMX ScriptService mistake &#8211; Invalid JSON primitive'>ASMX ScriptService mistake &#8211; Invalid JSON primitive</a></li>
<li><a href='http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/' rel='bookmark' title='ASMX and JSON &ndash; Common mistakes and misconceptions'>ASMX and JSON &ndash; Common mistakes and misconceptions</a></li>
<li><a href='http://encosia.com/asp-net-web-services-mistake-manual-json-serialization/' rel='bookmark' title='ASP.NET web services mistake: manual JSON serialization'>ASP.NET web services mistake: manual JSON serialization</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Continuing <a href="http://encosia.com/2010/03/03/asmx-and-json-common-mistakes-and-misconceptions/">my series of posts about ASMX services and JSON</a>, in this post I’m going to cover two common mistakes that plague the process of getting a project’s first ASMX ScriptService working: <strong>Installing System.Web.Extensions</strong> into the GAC and <strong>configuring your web.config</strong>.</p>
<h3>System.Web.Extensions (aka ASP.NET AJAX)</h3>
<p>The ability for ASMX services to return raw JSON is made possible by two key features originally added by the ASP.NET AJAX Extensions v1.0:</p>
<ul>
<li><strong>JavaScriptSerializer</strong> – <a href="http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(VS.100).aspx" target="_blank">The JavaScriptSerializer class</a> is the actual workhorse that translates back and forth between JSON strings and .NET CLR objects. Though less powerful than WCF’s DataContractJsonSerializer and third-party libraries like <a href="http://www.codeplex.com/Json" rel="nofollow" target="_blank">Json.NET</a>, JavaScriptSerializer is likely all you’ll ever need for simple AJAX callbacks. </li>
<li><strong>ScriptHandlerFactory</strong> – There are several more classes behind the scenes*, but the ScriptHandlerFactory is the tip of the iceberg that you&#8217;ll need to remember during configuration. Redirecting ASMX requests through this HttpHandler is what coordinates the pairing of ScriptService with JavaScriptSerializer to provide automatic JSON handling. </li>
</ul>
<p>Though both of these classes appear in the System.Web.Script namespace, they actually reside in ASP.NET AJAX&#8217;s System.Web.Extensions assembly. That has different implications depending on which version of ASP.NET your site targets:</p>
<ul>
<li><strong>1.x</strong> – No support for ScriptServices. A custom HttpHandler coupled with a third party library like <a href="http://james.newtonking.com/pages/json-net.aspx" target="_blank">Json.NET</a> is your best bet (if anyone has a good tutorial on doing this under 1.x, let me know so that I can link to it).</li>
<li><strong>2.0</strong> – ScriptServices are available in ASP.NET 2.0 with the installation of the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&amp;displaylang=en" rel="nofollow" target="_blank">ASP.NET AJAX Extensions v1.0</a>.
<ul>
<li>That means that <strong>the ASP.NET AJAX installer needs to be run on the server that hosts your site</strong>, not just on your local development machine.</li>
<li>For some of a ScriptService’s features to work in medium trust (i.e. shared hosting), the System.Web.Extensions assembly needs to be in your server’s global assembly cache (GAC). <a href="http://msmvps.com/blogs/luisabreu/archive/2007/11/22/stop-the-nonsense-don-t-put-the-system-web-extensions-dll-inside-your-bin-folder.aspx" target="_blank">Don’t waste your time trying to make it work in your site’s /bin directory</a>; insist that the extensions be properly installed on the server.</li>
</ul>
</li>
<li><strong>3.5+</strong> – As of .NET 3.5, System.Web.Extensions ships with the framework. No additional assemblies need be installed.</li>
</ul>
<p><em>* If you’re interested in the internals, I highly recommend downloading </em><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=ef2c1acc-051a-4fe6-ad72-f3bed8623b43&amp;DisplayLang=en" rel="nofollow" target="_blank">the ASP.NET AJAX Extensions v1.0 source</a><em></em><em> and taking a look at ScriptHandlerFactory, RestHandlerFactory, and RestHandler. Though the classes have changed slightly since v1.0, they are still very similar.</em></p>
<h3>Rerouting the ASMX handler via web.config</h3>
<p>With the System.Web.Extensions assembly installed in the GAC, the remaining configuration step is an element in your site’s web.config. To take advantage of the ScriptService functionality, <strong>ASP.NET must be instructed to reroute ASMX requests through the ScriptHandlerFactory instead of ASP.NET’s standard ASMX handler</strong>.</p>
<p>This step is often unnecessary. The project templates in ASP.NET 3.5+ include all the necessary configuration elements, and ASP.NET 2.0 sites created with the “AJAX Enabled” templates are also pre-configured correctly.</p>
<p>However, if you find yourself unable to coax JSON out of an ASMX ScriptService, <strong>verifying your web.config is one of the best first steps in troubleshooting the issue</strong>. Whether due to a web.config generated by an older project template, accidental modification, or other issues, missing the httpHandlers web.config setting is a very common pitfall.</p>
<p>What should appear varies slightly depending on which version of ASP.NET your project targets. Regardless of your framework version, the config elements should be added to the &lt;httpHandlers&gt; section and are the only elements necessary. The <a href="http://www.asp.net/AJAX/documentation/live/ConfiguringASPNETAJAX.aspx" rel="nofollow" target="_blank">variety of other config items required for the UpdatePanel and ScriptManager</a> aren’t crucial to the ScriptService functionality.</p>
<h4>ASP.NET 2.0 (with the ASP.NET AJAX Extensions installed)</h4>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httphandlers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;remove</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;*.asmx&quot;</span> <span style="color: #000066;">verb</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;*.asmx&quot;</span> <span style="color: #000066;">verb</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000066;">Culture</span>=neutral, <span style="color: #000066;">validate</span>=<span style="color: #ff0000;">&quot;false&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;System.Web.Script.Services.ScriptHandlerFactory, </span>
<span style="color: #009900;">                 System.Web.Extensions, Version=1.0.61025.0,</span>
<span style="color: #009900;">                 PublicKeyToken=31bf3856ad364e35&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httphandlers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<h4>ASP.NET 3.5</h4>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httphandlers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;remove</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;*.asmx&quot;</span> <span style="color: #000066;">verb</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;*.asmx&quot;</span> <span style="color: #000066;">verb</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000066;">Culture</span>=neutral, <span style="color: #000066;">validate</span>=<span style="color: #ff0000;">&quot;false&quot;</span></span>
<span style="color: #009900;">           <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;System.Web.Script.Services.ScriptHandlerFactory, </span>
<span style="color: #009900;">                 System.Web.Extensions, Version=3.5.0.0,</span>
<span style="color: #009900;">                 PublicKeyToken=31bf3856ad364e35&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httphandlers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<h4>ASP.NET 4</h4>
<p>Thankfully, <a href="http://www.asp.net/LEARN/whitepapers/aspnet4/default.aspx#_TOC1_1" rel="nofollow" target="_blank">ASP.NET 4 has taken steps to reverse the trend of ever-enlarging baseline web.config files</a>. By moving common configuration items such as the ScriptService’s HttpHandler to the default machine.config, each individual site need not include those configuration elements in their specific web.config files.</p>
<p>Unless you go out of your way to manually remove their HttpHandler, ASMX ScriptServices will work automatically in any ASP.NET 4 site.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/' rel='bookmark' title='ASMX ScriptService mistake &#8211; Invalid JSON primitive'>ASMX ScriptService mistake &#8211; Invalid JSON primitive</a></li>
<li><a href='http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/' rel='bookmark' title='ASMX and JSON &ndash; Common mistakes and misconceptions'>ASMX and JSON &ndash; Common mistakes and misconceptions</a></li>
<li><a href='http://encosia.com/asp-net-web-services-mistake-manual-json-serialization/' rel='bookmark' title='ASP.NET web services mistake: manual JSON serialization'>ASP.NET web services mistake: manual JSON serialization</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/">ASMX ScriptService mistake: Installation and configuration</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>ASMX and JSON &#8211; Common mistakes and misconceptions</title>
		<link>http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/</link>
		<comments>http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 09:02:37 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASMX Mistakes and Misconceptions]]></category>
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=971</guid>
		<description><![CDATA[While we were recording episode 5 of Mastering jQuery, I found myself running down a lengthy list of misconceptions and potential pitfalls when it comes to using ASMX services for AJAX callbacks. After years of fielding questions revolving around that topic, I suppose I’ve developed a decent handle on the issues most often encountered. To [...]
Related posts:<ol>
<li><a href='http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/' rel='bookmark' title='ASMX ScriptService mistake &#8211; Invalid JSON primitive'>ASMX ScriptService mistake &#8211; Invalid JSON primitive</a></li>
<li><a href='http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/' rel='bookmark' title='ASMX ScriptService mistake: Installation and configuration'>ASMX ScriptService mistake: Installation and configuration</a></li>
<li><a href='http://encosia.com/are-you-making-these-3-common-aspnet-ajax-mistakes/' rel='bookmark' title='Are you making these 3 common ASP.NET AJAX mistakes?'>Are you making these 3 common ASP.NET AJAX mistakes?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>While we were recording <a href="http://tekpub.com/view/jquery/5" target="_blank">episode 5 of Mastering jQuery</a>, I found myself running down a lengthy list of misconceptions and potential pitfalls when it comes to using ASMX services for AJAX callbacks. After years of fielding questions revolving around that topic, I suppose I’ve developed a decent handle on the issues most often encountered.</p>
<p>To preemptively surface some of that commonly requested information, I’m going to publish a series of relatively short posts, each describing one mistake or misconception that I’ve seen come up frequently.</p>
<p>To get started, I want to cover one of the most fundamental of these misconceptions:  That ASMX services can&#8217;t return JSON.</p>
<h3>Misconception: ASMX services are limited to XML</h3>
<p>One of the most stubbornly persistent misconceptions about ASMX services is the rumor that they are limited to returning XML. With that notion mind, many developers understandably avoid them for client-side AJAX callbacks. When every byte counts, raw JSON is always preferable to the bloat of XML.</p>
<p>However, the introduction of <strong>ASP.NET AJAX removed that XML limitation</strong>.</p>
<p>In any ASP.NET 2.0+ AJAX enabled site, one of ASP.NET AJAX’s additions is something called the <strong>ScriptService</strong>. When a ScriptService is called in the correct manner, it automatically returns its result serialized as JSON instead of XML.</p>
<p>In fact, these <a href="http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/">ASMX ScriptServices even accept their parameters as JSON</a>.</p>
<h3>The ASP.NET AJAX “ScriptService”</h3>
<p>If you’ve created an ASMX service in the past few years, you’ve probably seen this blurb at the beginning of the default template:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">// To allow this Web Service to be called from script, </span>
<span style="color: #008080; font-style: italic;">//   using ASP.NET AJAX, uncomment the following line. </span>
<span style="color: #008080; font-style: italic;">// [System.Web.Script.Services.ScriptService] </span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> WebService <span style="color: #008000;">:</span> <span style="color: #000000;">System.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Services</span></span>.<span style="color: #0000FF;">WebService</span> <span style="color: #000000;">&#123;</span></pre></div></div>

<p>Since it never explicitly mentions JSON <em>and</em> implies a tight coupling with ASP.NET AJAX, it’s easy to understand why the ScriptService’s true power sometimes goes unnoticed. Thankfully, that attribute does much more than simply expose ASP.NET AJAX specific functionality.</p>
<p>In fact, <strong>the ScriptService attribute enables all of an ASMX service’s methods to respond with raw JSON</strong> if they are requested correctly. For example, these ScriptServices can easily <a href="http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/">send and receive JSON in conjunction with a third party library</a>, without a ScriptManager or MicrosoftAjax.js anywhere to be seen.</p>
<h3>Two simple requirements</h3>
<p>As I alluded to earlier, the one stipulation is that <strong>these ScriptServices only return JSON serialized results if they are requested properly</strong>. Otherwise, even a service marked with the attribute will return XML instead of JSON. I can only assume that’s part of the reason for the misconception that ASMX services cannot respond with JSON.</p>
<p>Scott Guthrie has a great post on <a href="http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx" target="_blank">the specific requirements for coercing JSON out of ScriptServices</a>. To summarize that, requests to the service methods must meet two requirements:</p>
<ul>
<li><strong>Content-Type</strong> – The HTTP request <em>must</em> declare a content-type of application/json. This informs the ScriptService that it will receive its parameters as JSON and that it should respond in kind.</li>
<li><strong>HTTP Method</strong> – By default, the HTTP request must be a POST request. It <em>is</em> possible to circumvent this requirement, but <a href="http://haacked.com/archive/2009/06/25/json-hijacking.aspx" target="_blank">it is advisable to stick with HTTP POST requests when dealing with JSON</a>.</li>
</ul>
<p>That’s it.</p>
<p>As long as those two requirements are satisfied, anything from low-level XMLHttpRequest code, to third-party libraries like jQuery, to ASP.NET AJAX itself can easily retrieve JSON serialized data from ASMX services.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/asmx-scriptservice-mistake-invalid-json-primitive/' rel='bookmark' title='ASMX ScriptService mistake &#8211; Invalid JSON primitive'>ASMX ScriptService mistake &#8211; Invalid JSON primitive</a></li>
<li><a href='http://encosia.com/asmx-scriptservice-mistakes-installation-and-configuration/' rel='bookmark' title='ASMX ScriptService mistake: Installation and configuration'>ASMX ScriptService mistake: Installation and configuration</a></li>
<li><a href='http://encosia.com/are-you-making-these-3-common-aspnet-ajax-mistakes/' rel='bookmark' title='Are you making these 3 common ASP.NET AJAX mistakes?'>Are you making these 3 common ASP.NET AJAX mistakes?</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/">ASMX and JSON &ndash; Common mistakes and misconceptions</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>How you can force the Ajax Script Loader to use jQuery 1.4</title>
		<link>http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/</link>
		<comments>http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 05:24:57 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=962</guid>
		<description><![CDATA[If you’ve already begun using Microsoft’s new Ajax Script Loader with a CDN-hosted version of jQuery, today’s release of jQuery 1.4 may have left you wondering how to upgrade. Personally, I didn’t want to wait on a new version of Start.js, nor did I want to abandon the script loader now that I’ve become accustomed [...]
Related posts:<ol>
<li><a href='http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
<li><a href='http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
<li><a href='http://encosia.com/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='3 mistakes to avoid when using jQuery with ASP.NET AJAX'>3 mistakes to avoid when using jQuery with ASP.NET AJAX</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>If you’ve already begun using Microsoft’s new <a href="http://www.asp.net/ajaxLibrary/Ajax%20Script%20Loader.ashx" target="_blank">Ajax Script Loader</a> with a CDN-hosted version of jQuery, today’s release of jQuery 1.4 may have left you wondering how to upgrade. Personally, I didn’t want to wait on a new version of Start.js, nor did I want to abandon the script loader now that I’ve become accustomed to its benefits.</p>
<p>No doubt, an upcoming ASP.NET Ajax Library iteration will update Start.js’ jQuery definition to reference jQuery 1.4.x. Regardless, <strong>knowing how to patch the script loader on your own terms is something that will be of recurring usefulness</strong>.</p>
<p>Luckily, <a href="http://weblogs.asp.net/bleroy/archive/2009/11/23/enabling-the-asp-net-ajax-script-loader-for-your-own-scripts.aspx" target="_blank">the script loader is open and extensible</a> enough that it’s possible to change which script versions are used. So, I want to briefly show you <strong>how the script loader defines JavaScript includes</strong> and how you can <strong>patch those definitions without modifying Start.js</strong> itself.</p>
<h3>Using the script loader to inject jQuery</h3>
<p>If you aren’t familiar with the script loader itself or with using it to asynchronously request jQuery, I recommend checking out <a href="http://www.asp.net/ajaxlibrary/Ajax%20Script%20Loader.ashx" target="_blank">its documentation and examples on the new ASP.NET Ajax Wiki</a>.</p>
<p>To use it most basically, simply include a reference to Start.js either locally or on the Microsoft CDN, and then use this JavaScript to instruct the script loader to inject jQuery into the page:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Instruct the script loader to request</span>
<span style="color: #006600; font-style: italic;">//  jQuery in the background.</span>
Sys.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span>Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This callback runs later, after jQuery</span>
<span style="color: #006600; font-style: italic;">//  has been asynchronously loaded.</span>
Sys.<span style="color: #660066;">onReady</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Loaded jQuery &quot;</span> <span style="color: #339933;">+</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">jquery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Monitoring the request in Firebug illuminates what that Sys.require statement triggered in the background:</p>
<p><img style="border: #333 1px solid;" alt="Observing the script loader&#39;s default jQuery injection behavior" src="http://encosia.com/blog/wp-content/uploads/2010/01/script-loader-default.png" width="490" height="142" /></p>
<p>As you can see, the end result is pretty straightforward. The primary benefit of this asynchronous loading technique is that <strong>scripts loaded through the script loader are non-blocking and may be loaded in parallel</strong>. By contrast, JavaScript includes referenced through HTML script elements block all rendering and further requests until they are parsed and executed. <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/" target="_blank">The difference is often significant</a>.</p>
<p>Now, if only it were injecting jQuery 1.4 instead of 1.3.2.</p>
<h3>Understanding how Sys.scripts.jQuery is defined</h3>
<p>The Sys.scripts.jQuery parameter to the script loader is actually just a JavaScript object that defines a few parameters about the include. Here is how that is defined in Start.js (edited slightly for readability here):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> path <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>window.<span style="color: #660066;">location</span>.<span style="color: #660066;">protocol</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;https&quot;</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">&quot;https&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http&quot;</span><span style="color: #009900;">&#41;</span> 
           <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;://ajax.microsoft.com/ajax/&quot;</span><span style="color: #339933;">;</span>
&nbsp;
loader.<span style="color: #660066;">defineScripts</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>
 <span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;jQuery&quot;</span><span style="color: #339933;">,</span>
   releaseUrl<span style="color: #339933;">:</span> path <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;jquery/jquery-1.3.2.min.js&quot;</span><span style="color: #339933;">,</span>
   debugUrl<span style="color: #339933;">:</span> path <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;jquery/jquery-1.3.2.js&quot;</span><span style="color: #339933;">,</span>
   isLoaded<span style="color: #339933;">:</span> <span style="color: #339933;">!!</span>window.<span style="color: #660066;">jQuery</span>
 <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>If you’re using a local copy of Start.js, one option is to modify this jQuery script definition inside Start.js itself. However, I discourage that alternative. Not only would it require constant, manual maintenance after every new release, but it isn’t an option when using <a href="http://www.asp.net/ajaxLibrary/cdn.ashx" target="_blank">the Microsoft Ajax CDN’s</a> copy of Start.js.</p>
<h3>Defining a new target for it</h3>
<p>Another option is to <strong>simply modify the Sys.scripts.jQuery object itself</strong>. Letting Start.js initialize the definition with jQuery 1.3.2’s path doesn’t hurt anything as long as we redefine it before calling Sys.require.</p>
<p>Inspecting the Sys.scripts collection in Firebug reveals how straightforward that modification will be:</p>
<p><img style="border: #333 1px solid;" alt="Inspecting Sys.scripts.jQuery in Firebug" src="http://encosia.com/blog/wp-content/uploads/2010/01/Sys.scripts.jQuery-inspection.png" width="490" height="124" /></p>
<p>Thanks to to <a href="http://encosia.com/2009/09/21/updated-see-how-i-used-firebug-to-learn-jquery/" target="_blank">the power of interactively interrogating the object in Firebug</a>, it becomes clear that updating the releaseUrl and debugUrl properties of that object should be all that is necessary.</p>
<h3>Updating the example to use jQuery 1.4</h3>
<p>Because jQuery 1.4 isn’t available on the Microsoft CDN yet, I’m going to target <a href="http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/">Google’s AJAX Libraries CDN for jQuery</a> instead. Once Microsoft’s CDN is updated with jQuery 1.4.x, this approach will work for either CDN.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// These re-definitions must be executed after </span>
<span style="color: #006600; font-style: italic;">//  Start.js, but before Sys.require.</span>
<span style="color: #003366; font-weight: bold;">var</span> CDN <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;http://ajax.googleapis.com/ajax/libs&quot;</span><span style="color: #339933;">;</span>
&nbsp;
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span>.<span style="color: #660066;">releaseUrl</span> <span style="color: #339933;">=</span> CDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jquery/1.4.1/jquery.min.js&quot;</span><span style="color: #339933;">;</span>
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span>.<span style="color: #660066;">debugUrl</span>   <span style="color: #339933;">=</span> CDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jquery/1.4.1/jquery.js&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Instruct the script loader to request</span>
<span style="color: #006600; font-style: italic;">//  jQuery in the background.</span>
Sys.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span>Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This callback runs later, after jQuery</span>
<span style="color: #006600; font-style: italic;">//  has been asynchronously loaded.</span>
Sys.<span style="color: #660066;">onReady</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  console.<span style="color: #660066;">log</span><span style="color: #3366CC;">&quot;Loaded jQuery &quot;</span> <span style="color: #339933;">+</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">jquery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That’s all there is to it. Reviewing the requests in Firebug again, you can see that the same Sys.require statement is indeed now loading jQuery 1.4 from Google’s CDN:</p>
<p><img style="border: #333 1px solid;" alt="Observing the script loader&#39;s behavior after modifying Sys.scripts.jQuery" src="http://encosia.com/blog/wp-content/uploads/2010/01/script-loader-modified.png" width="490" /></p>
<h3>Bonus: jQuery Validate 1.6</h3>
<p>As I write this, Start.js’ definition for Sys.scripts.jQueryValidate is still targeting version 1.5.5 of the plugin, but <a href="http://www.asp.net/ajaxLibrary/CDNjQueryValidate16.ashx" target="_blank">1.6 is the current version</a>.</p>
<p>Using what&#8217;s been covered in this post, pointing the script loader at the newest version of jQuery Validate is no problem:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> MSCDN <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;http://ajax.microsoft.com/ajax&quot;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> GoogCDN <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;http://ajax.googleapis.com/ajax/libs&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Please forgive my ugly formatting to make this fit. Do not try </span>
<span style="color: #006600; font-style: italic;">//  this at home (unless your editor is only 492px too).</span>
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span>.<span style="color: #660066;">releaseUrl</span> <span style="color: #339933;">=</span> 
  GoogCDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jquery/1.4.1/jquery.min.js&quot;</span><span style="color: #339933;">;</span>
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span>.<span style="color: #660066;">debugUrl</span> <span style="color: #339933;">=</span> 
  GoogCDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jquery/1.4.1/jquery.js&quot;</span><span style="color: #339933;">;</span>
&nbsp;
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQueryValidate</span>.<span style="color: #660066;">releaseUrl</span> <span style="color: #339933;">=</span> 
  MSCDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jQuery.Validate/1.6/jQuery.Validate.min.js&quot;</span><span style="color: #339933;">;</span>
Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQueryValidate</span>.<span style="color: #660066;">debugUrl</span> <span style="color: #339933;">=</span> 
  MSCDN <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/jQuery.Validate/1.6/jQuery.Validate.js&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Instruct the script loader to request</span>
<span style="color: #006600; font-style: italic;">//  jQuery and jQuery Validate in the background.</span>
Sys.<span style="color: #660066;">require</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQuery</span><span style="color: #339933;">,</span> Sys.<span style="color: #660066;">scripts</span>.<span style="color: #660066;">jQueryValidate</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This callback runs later, after both jQuery</span>
<span style="color: #006600; font-style: italic;">//  and jQuery Validate have been loaded.</span>
Sys.<span style="color: #660066;">onReady</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Loaded jQuery &quot;</span> <span style="color: #339933;">+</span> jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">jquery</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The jQuery Validate situation is a good example of why knowing how to update these script definitions yourself is worthwhile. Because the script loader was designed to be so flexible, there’s no need to wait on a new release of Start.js or give up its benefits.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/' rel='bookmark' title='Using jQuery to directly call ASP.NET AJAX page methods'>Using jQuery to directly call ASP.NET AJAX page methods</a></li>
<li><a href='http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/' rel='bookmark' title='Simplify calling ASP.NET AJAX services from jQuery'>Simplify calling ASP.NET AJAX services from jQuery</a></li>
<li><a href='http://encosia.com/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/' rel='bookmark' title='3 mistakes to avoid when using jQuery with ASP.NET AJAX'>3 mistakes to avoid when using jQuery with ASP.NET AJAX</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/">How you can force the Ajax Script Loader to use jQuery 1.4</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Mastering jQuery now available at TekPub</title>
		<link>http://encosia.com/mastering-jquery-now-available-at-tekpub/</link>
		<comments>http://encosia.com/mastering-jquery-now-available-at-tekpub/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 14:52:42 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=951</guid>
		<description><![CDATA[If you haven’t been following the progress of Rob Conery and James Avery’s new venture, TekPub, you’ve been missing out on some great instructional videos. I especially like that they trend slightly Alt.NET, giving you more balanced information than is sometimes available from “official” .NET screencasts. For the past few weeks, I’ve been working with [...]
Related posts:<ol>
<li><a href='http://encosia.com/announcing-my-new-tekpub-series-where-you-call-the-shots/' rel='bookmark' title='Announcing my new TekPub series, where you call the shots'>Announcing my new TekPub series, where you call the shots</a></li>
<li><a href='http://encosia.com/im-giving-away-10-free-months-of-tekpub-this-week/' rel='bookmark' title='I&#8217;m giving away 10 free months of TekPub this week'>I&#8217;m giving away 10 free months of TekPub this week</a></li>
<li><a href='http://encosia.com/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/' rel='bookmark' title='Hear me talk jQuery and ASP.NET on the jQuery Podcast'>Hear me talk jQuery and ASP.NET on the jQuery Podcast</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://tekpub.com/view/jquery/1?ref=encosia" target="_blank"><img border="0" alt="Mastering jQuery" src="http://encosia.com/blog/wp-content/uploads/2009/12/tekpub-mastering-jquery.jpg" width="492" height="242" /></a></p>
<p>If you haven’t been following the progress of Rob Conery and James Avery’s new venture, <a href="http://tekpub.com" target="_blank">TekPub</a>, you’ve been missing out on some great instructional videos. I especially like that they trend slightly Alt.NET, giving you more balanced information than is sometimes available from “official” .NET screencasts.</p>
<p>For the past few weeks, I’ve been working with James to record a series of episodes for TekPub myself: <strong>Mastering jQuery</strong>.</p>
<blockquote><p>Mastering jQuery walks through the basics of using jQuery, the revolutionary JavaScript framework that makes writing client-side code fun and easy, and then dives into the details of writing AJAX enabled ASP.NET MVC and ASP.NET Web Forms applications. We will also cover popular plugins and extending jQuery in future episodes.</p></blockquote>
<p>Today, the first video in that series is available: <a href="http://tekpub.com/view/jquery/1?ref=encosia" target="_blank">Getting Started with jQuery</a>.</p>
<blockquote><p>In this episode we cover the basics of getting started with jQuery. We start with a basic HTML page and show how to include jQuery, how to write your first code, and explain all of the moving pieces and how they work.</p></blockquote>
<p>If you’ve been following my site and working with jQuery already, the first episode may sound elementary, but there’s going to be something for everyone before the series is finished. By the third episode, we’re already into topics like making <strong>AJAX calls to MVC controller actions</strong> and <strong>progressively enhancing an entry form</strong> with the jQuery form plugin.</p>
<p>I hope you&#8217;ll head over to TekPub, and <a href="http://tekpub.com/view/jquery/1?ref=encosia" target="_blank">have a look for yourself</a>.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/announcing-my-new-tekpub-series-where-you-call-the-shots/' rel='bookmark' title='Announcing my new TekPub series, where you call the shots'>Announcing my new TekPub series, where you call the shots</a></li>
<li><a href='http://encosia.com/im-giving-away-10-free-months-of-tekpub-this-week/' rel='bookmark' title='I&#8217;m giving away 10 free months of TekPub this week'>I&#8217;m giving away 10 free months of TekPub this week</a></li>
<li><a href='http://encosia.com/hear-me-talk-jquery-and-asp-net-on-the-jquery-podcast/' rel='bookmark' title='Hear me talk jQuery and ASP.NET on the jQuery Podcast'>Hear me talk jQuery and ASP.NET on the jQuery Podcast</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/mastering-jquery-now-available-at-tekpub/">Mastering jQuery now available at TekPub</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/mastering-jquery-now-available-at-tekpub/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/mastering-jquery-now-available-at-tekpub/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Emulate ASP.NET validation groups with jQuery validation</title>
		<link>http://encosia.com/asp-net-webforms-validation-groups-with-jquery-validation/</link>
		<comments>http://encosia.com/asp-net-webforms-validation-groups-with-jquery-validation/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 17:51:37 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=948</guid>
		<description><![CDATA[In my most recent post, I demonstrated a workaround to allow using the jQuery validation plugin with WebForms pages. The basic idea was to trigger validation only on submissions that occurred within a single logical form, instead of catching submissions anywhere on WebForms’ all-encompassing physical form. This approach worked fine for a single logical form, [...]
Related posts:<ol>
<li><a href='http://encosia.com/using-jquery-validation-with-asp-net-webforms/' rel='bookmark' title='Using jQuery validation with ASP.NET WebForms'>Using jQuery validation with ASP.NET WebForms</a></li>
<li><a href='http://encosia.com/using-jquery-to-display-a-modal-updatepanel-confirmation/' rel='bookmark' title='Using jQuery to display a modal UpdatePanel confirmation'>Using jQuery to display a modal UpdatePanel confirmation</a></li>
<li><a href='http://encosia.com/use-jquery-and-quicksearch-to-interactively-search-any-data/' rel='bookmark' title='Use jQuery and quickSearch to interactively search any data'>Use jQuery and quickSearch to interactively search any data</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>In my most recent post, I demonstrated a workaround to allow <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/" target="_blank">using the jQuery validation plugin with WebForms pages</a>. The basic idea was to trigger validation only on submissions that occurred within a single logical form, instead of catching submissions anywhere on WebForms’ all-encompassing physical form.</p>
<p>This approach worked fine for a single logical form, but wasn&#8217;t robust enough when handling validation for multiple logical forms on a single page. Additionally, it did not properly handle the enter key, allowing users to (perhaps accidentally) slip past validation if they simply hit the enter key within a TextBox.</p>
<p>In this post, we will continue by refining the solution from last time. So, if you haven’t read the previous post, familiarize yourself with it first. Specifically, this post will cover how to <strong>implement an analogue of WebForms’ ValidationGroup</strong>, use that to <strong>independently validate multiple form regions</strong>, <strong>handle the enter key</strong>, and <strong>refactor the final solution</strong> to minimize duplicated code.</p>
<h3>ValidationGroups</h3>
<p>In WebForms, we have the concept of a <strong><a href="http://msdn.microsoft.com/en-us/library/ms227424.aspx" rel="nofollow" target="_blank">ValidationGroup</a></strong> to mitigate the issues that come with wrapping the entire page in a single form element. Whether right or wrong in principle, this scheme does a pretty good job of keeping the ASP.NET Validation controls from getting their wires crossed on complex forms.</p>
<p>However, using ASP.NET’s ValidationGroups requires that you use the WebForms validation controls, which generates quite a bit of cruft in your markup and injects two additional script references on your page.</p>
<p><img style="border: 1px solid #000;" alt="An example of some of the client-side code the ASP.NET Validators generates" src="http://encosia.com/blog/wp-content/uploads/2009/11/WebForms-validator-output.png" width="490" height="111" /></p>
<p>If you’re like me, trying to trend away from client-heavy WebForms pages <strong>these side-effects are prohibitive</strong>.</p>
<h3>Emulating Validation Groups</h3>
<p>Though its implementation renders a bit messy on the client-side, the WebForms paradigm of a ValidationGroup is exactly what we need for segregating our physical form element into logical forms. In fact, I’m going to use the same nomenclature in this example (ValidationGroup and CausesValidation).</p>
<p>Using CSS classes as flags is a great way to emulate that concept in plain (X)HTML markup. Especially when using jQuery, CSS “flags” are a great way to tag elements with arbitrary attributes, that are easy to find with simple DOM selectors later. Taking the form shown in my previous post and tagging its fieldsets with a validationGroup class, we end up with this markup:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fieldset</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;validationGroup&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;legend&gt;</span></span>Returning customer?  Login here<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/legend&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #060; font-style: italic;">&lt;!-- Username and Password labels and inputs here --&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fieldset&gt;</span></span></pre></div></div>

<p>Not a very large change, but it allows us to keep these logical forms separate, both when performing validation and when initially setting up their validation triggers.</p>
<h3>Creating a CausesValidation counterpart</h3>
<p>ValidationGroups may control the organization of logical forms, but it’s the controls marked with the CausesValidation property that drive validation of those forms. In similar fashion, we need a way to indicate which elements should trigger our own emulation of WebForms’ grouped validation.</p>
<p>Sticking with the same naming scheme and CSS flagging technique, it makes sense to tag our Button controls with a .causesValidation class:</p>

<div class="wp_syntax"><div class="code"><pre class="asp" style="font-family:monospace;">&lt;fieldset class=&quot;validationGroup&quot;&gt;
  &lt;legend&gt;Returning customer?  Login here&lt;/legend&gt;
&nbsp;
  <span style="color: #060; font-style: italic;">&lt;!-- Username and Password labels and inputs here --&gt;</span>
&nbsp;
  &lt;asp:Button runat=&quot;server&quot; ID=&quot;Login&quot; Text=&quot;Login&quot; 
              CssClass=&quot;causesValidation&quot; /&gt;
&lt;/fieldset&gt;</pre></div></div>

<p>Now we just need to wire up functionality to make those causesValidation flags actually do something.</p>
<h3>Acting on the validationGroup flag</h3>
<p>With the markup modified to allow selective targeting of the validation groups, the next step is implementing validation functionality that leverages that targeting. Using jQuery’s powerful CSS-based selectors, that isn’t difficult:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> onsubmit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Search for controls marked with the causesValidation flag </span>
  <span style="color: #006600; font-style: italic;">//  that are contained anywhere within elements marked as </span>
  <span style="color: #006600; font-style: italic;">//  validationGroups, and wire their click event up.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup .causesValidation'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Ascend from the button that triggered this click event </span>
    <span style="color: #006600; font-style: italic;">//  until we find a container element flagged with </span>
    <span style="color: #006600; font-style: italic;">//  .validationGroup and store a reference to that element.</span>
    <span style="color: #003366; font-weight: bold;">var</span> $group <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">parents</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> isValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Descending from that .validationGroup element, find any input</span>
    <span style="color: #006600; font-style: italic;">//  elements within it, iterate over them, and run validation on </span>
    <span style="color: #006600; font-style: italic;">//  each of them.</span>
    $group.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':input'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        isValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isValid<span style="color: #009900;">&#41;</span>
      evt.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>Note: For more explanation of any uncommented code above, be sure to see <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/" target="_blank">the previous post in this series</a>. Those parts are explained in detail there.</em></p>
<p>This sets up a click event handler on any element flagged with the causesValidation class; the two Button controls in our case. When those raise click events, we start at the triggering element and use <a href="http://docs.jquery.com/Traversing/parents#expr" target="_blank">the parents() traversal method</a> to search upward for the nearest parent flagged as a validationGroup.</p>
<p>In this example, that will find a reference to the fieldset which contains the Button control that triggers the click event (e.g. if the user clicks the Login Button, then $group will store a reference to the first fieldset element).</p>
<p>With that reference to the the logical form requiring validation, <a href="http://docs.jquery.com/Traversing/find#expr" target="_blank">jQuery’s find() traversal method</a> allows us to select a set of all the input elements within just that region of the page. Note that this will also include the Button control that triggered the event, but since the valid() method returns <em>true</em> for elements that don’t have validation rules configured, this doesn’t cause a problem.</p>
<p>From there, it’s straightforward to iterate over the appropriate input elements and validate each independently, using <a href="http://encosia.com/2009/11/04/using-jquery-validation-with-asp-net-webforms/" target="_blank">the valid() trick covered in the last post</a>.</p>
<h3>Handling the enter key</h3>
<p>At this point, everything works pretty well, so long as the user <em>clicks</em> on the Button controls to submit the logical forms. Unfortunately, things fall apart if the user triggers form submission by pressing enter in one of the form fields.</p>
<p>One way to fix that would be to handle the form’s onsubmit event, determine if an element flagged with the causesValidation class triggered the submission, and then run through our validation first. That’s perfectly valid, but <strong>I avoid that because it tends to clash with other functionality that handles the event</strong>; <a href="http://jquery.malsup.com/form/" target="_blank">the jQuery form plugin</a> for example.</p>
<p>The alternative that I prefer is to handle a validated field’s onkeydown event. That way, if the element does need to trigger validation, it can do so early, and get out of the way quickly otherwise.</p>
<p>Using jQuery’s cross-browser normalized event object, testing for the enter key is not difficult at all. When handling keyboard related events, one property of that object is <strong>keyCode</strong>. This property will contain the ASCII character code of the key which triggered the event. In the case of the enter key, that keyCode is <strong>13</strong>.</p>
<p>That in mind, this is a first iteration of adding enter key handling to our existing validation code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Select any input[type=text] elements within a validation group</span>
<span style="color: #006600; font-style: italic;">//  and attach keydown handlers to all of them.</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup :text'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">keydown</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Only execute validation if the key pressed was enter.</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>evt.<span style="color: #660066;">keyCode</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">13</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Validation code goes here.</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Whether the form is submitted by clicking a button or hitting the enter key within one of our validation groups’ text fields, the appropriate inputs will be validated, error messages displayed if necessary, and <strong>submission will only continue if the form is valid</strong>.</p>
<h3>Refactoring to eliminate duplication</h3>
<p>After adding the keydown handler, everything works great, but it’s no good to have that validation code duplicated for both the click and keydown handlers. By passing around a reference to the jQuery event object, we can reuse the same validation code for both event types and make the code much more concise:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Initialize validation on the entire ASP.NET form.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// This prevents validation from running on every</span>
    <span style="color: #006600; font-style: italic;">//  form submission by default.</span>
    onsubmit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Search for controls marked with the causesValidation flag </span>
  <span style="color: #006600; font-style: italic;">//  that are contained anywhere within elements marked as </span>
  <span style="color: #006600; font-style: italic;">//  validationGroups, and wire their click event up.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup .causesValidation'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span>ValidateAndSubmit<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Select any input[type=text] elements within a validation group</span>
  <span style="color: #006600; font-style: italic;">//  and attach keydown handlers to all of them.</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup :text'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">keydown</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Only execute validation if the key pressed was enter.</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>evt.<span style="color: #660066;">keyCode</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">13</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      ValidateAndSubmit<span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> ValidateAndSubmit<span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Ascend from the button that triggered this click event </span>
  <span style="color: #006600; font-style: italic;">//  until we find a container element flagged with </span>
  <span style="color: #006600; font-style: italic;">//  .validationGroup and store a reference to that element.</span>
  <span style="color: #003366; font-weight: bold;">var</span> $group <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>evt.<span style="color: #660066;">currentTarget</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">parents</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.validationGroup'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003366; font-weight: bold;">var</span> isValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Descending from that .validationGroup element, find any input</span>
  <span style="color: #006600; font-style: italic;">//  elements within it, iterate over them, and run validation on </span>
  <span style="color: #006600; font-style: italic;">//  each of them.</span>
  $group.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':input'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      isValid <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// If any fields failed validation, prevent the button's click </span>
  <span style="color: #006600; font-style: italic;">//  event from triggering form submission.</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isValid<span style="color: #009900;">&#41;</span>
    evt.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>First, the validation code is refactored into a separate function: <strong>Validate</strong>.</p>
<p>Since it needs the ability to conditionally call preventDefault in order to stop form submission, the function accepts the event handlers’ jQuery event object as a parameter.</p>
<p>In fact, because $(this) is a reasonable place to begin the parents() traversal for either event that may call the method, very little refactoring is necessary.</p>
<p>The one thing that may seem strange is that the Validate function is being passed as a click handler without any parameters. <strong>The reason that this works is because the Validate function is defined with the same signature that jQuery expects</strong>. Because of that alignment, Validate will automatically be provided with the same event object that we’ve been using in anonymous callback functions thus far.</p>
<h3>Calculated readability</h3>
<p>Note that I attached keydown handlers to <em>all</em> of the text inputs within a validation group, <strong>regardless of whether or not they are actually validated fields</strong>. Similarly, you may have noticed that the click handler finds every input element within its validation group, even if those inputs aren’t marked for validation. This may seem like an oversight, but it’s an intended readability compromise.</p>
<p>You <em>could</em> modify the selector to be more precise, selecting only fields flagged with validation classes (e.g. <em>required</em>, <em>email</em>, <em>number</em>, etc). However, this gets messy when you consider <a href="http://docs.jquery.com/Plugins/Validation#List_of_built-in_Validation_methods" rel="nofollow" target="_blank">the wide variety of classes that are valid for tagging elements with jQuery validation functionality</a>.</p>
<p>Rather than be precisely specific, I rely on the fact that <strong>jQuery validation’s valid() method returns <em>true</em> for elements which are not configured for validation</strong>. So, even if we do end up checking the validation status of a few irrelevant input fields, it won’t adversely impact the outcome of the validation process.</p>
<p>There are performance penalties to performing validation on these unnecessary elements, but it is negligible for a reasonably sized form. The ancillary inputs would have to number in the thousands before the penalty were noticeable, at which no one will probably ever successfully complete it anyway!</p>
<h3>Conclusion</h3>
<p>There are even more enhancements to be had, but I think this brings the solution to a point that it’s useful. With multiple logical forms handled and the perennially pesky enter key tamed, the majority of use cases should be covered.</p>
<p>The most troublesome issue still remaining is that <strong>care should be taken to avoid nesting container elements with the validationGroup class on them</strong>. Otherwise, the Validate() function will search “too high” and possibly hinge validation on input fields that are not intended. It’s an edge case (fixable if necessary), but something to keep in mind.</p>
<p>Another edge case is that, unlike the ASP.NET Validators, <strong>these validation groups can’t overlap</strong>. For my own use, this has never been an issue. I’m curious if that’s a real-world problem for any of you.</p>
<p>Finally, an entirely different approach well worth considering is <a href="http://john.rummell.info/john/blog/" target="_blank">John Rummell</a>’s <a href="http://xvalwebforms.codeplex.com/" rel="nofollow" target="_blank">xVal for Webforms</a>. Using Data Annotations to specify validation rules is gaining a lot of popularity, so it’s worth investigating options like this one. At the minimum, it will help you be more familiar with how validation is handled in ASP.NET MVC.</p>
<p>Hope that helps. Be sure to take a look at the source download to see everything pulled together and one extra usability feature that I didn’t have time to cover.</p>
<h3>Get the source</h3>
<p>If you&#8217;d like to browse through a complete working example of what&#8217;s been covered in this post, take a look at the companion project at GitHub. Or, if you&#8217;d like to download the entire project and run it in Visual Studio to see it in action yourself, grab the ZIP archive.</p>
<p><a href="https://github.com/Encosia/Encosia-Samples-WebForms-jQuery-Validation/tree/Part2" target="_blank" class="generalButton" style="width: 220px; float: left; text-align: center;">WebForms-jQuery-Validation on GitHub</a><a href="https://github.com/Encosia/Encosia-Samples-WebForms-jQuery-Validation/zipball/Part2" target="_blank" class="generalButton" style="width: 220px; float: right; text-align: center;">WebForms-jQuery-Validation.zip</a></p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/using-jquery-validation-with-asp-net-webforms/' rel='bookmark' title='Using jQuery validation with ASP.NET WebForms'>Using jQuery validation with ASP.NET WebForms</a></li>
<li><a href='http://encosia.com/using-jquery-to-display-a-modal-updatepanel-confirmation/' rel='bookmark' title='Using jQuery to display a modal UpdatePanel confirmation'>Using jQuery to display a modal UpdatePanel confirmation</a></li>
<li><a href='http://encosia.com/use-jquery-and-quicksearch-to-interactively-search-any-data/' rel='bookmark' title='Use jQuery and quickSearch to interactively search any data'>Use jQuery and quickSearch to interactively search any data</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/asp-net-webforms-validation-groups-with-jquery-validation/">Emulate ASP.NET validation groups with jQuery validation</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/asp-net-webforms-validation-groups-with-jquery-validation/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/asp-net-webforms-validation-groups-with-jquery-validation/feed/</wfw:commentRss>
		<slash:comments>83</slash:comments>
		</item>
		<item>
		<title>Using jQuery validation with ASP.NET WebForms</title>
		<link>http://encosia.com/using-jquery-validation-with-asp-net-webforms/</link>
		<comments>http://encosia.com/using-jquery-validation-with-asp-net-webforms/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 09:57:24 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=939</guid>
		<description><![CDATA[You’ve probably noticed that Jörn Zaefferer’s jQuery validation plugin has been gaining momentum in the ASP.NET community lately. Between Microsoft’s implied endorsement via ASP.NET MVC 2.0 integration and the plugin’s recent inclusion on the Microsoft AJAX CDN, adoption is only increasing. Unfortunately for those who don’t or can’t use ASP.NET MVC yet, using the validation [...]
Related posts:<ol>
<li><a href='http://encosia.com/asp-net-webforms-validation-groups-with-jquery-validation/' rel='bookmark' title='Emulate ASP.NET validation groups with jQuery validation'>Emulate ASP.NET validation groups with jQuery validation</a></li>
<li><a href='http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/' rel='bookmark' title='How you can force the Ajax Script Loader to use jQuery 1.4'>How you can force the Ajax Script Loader to use jQuery 1.4</a></li>
<li><a href='http://encosia.com/use-jquery-and-quicksearch-to-interactively-search-any-data/' rel='bookmark' title='Use jQuery and quickSearch to interactively search any data'>Use jQuery and quickSearch to interactively search any data</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="border: 1px solid #333;" title="Validation Sticker" border="0" alt="Validation Sticker" src="http://encosia.com/blog/wp-content/uploads/2009/11/validation-sticker.jpg" width="490" height="138" /></p>
<p>You’ve probably noticed that Jörn Zaefferer’s <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/" target="_blank">jQuery validation plugin</a> has been gaining momentum in the ASP.NET community lately. Between Microsoft’s implied endorsement via <a href="http://haacked.com/archive/2009/10/01/asp.net-mvc-preview-2-released.aspx" target="_blank">ASP.NET MVC 2.0 integration</a> and <a href="http://www.asp.net/ajax/CDN/#5" target="_blank">the plugin’s recent inclusion on the Microsoft AJAX CDN</a>, adoption is only increasing. Unfortunately for those who don’t or can’t use ASP.NET MVC yet, using the validation plugin within WebForms applications can be tricky.</p>
<p>Because the WebForms Postback model requires that the entire page be contained within a single form element, form submissions that shouldn’t trigger validation are likely. ASP.NET’s built-in validation controls solve this with ValidationGroups and the CausesValidation property, but that doesn’t help if you’d prefer to use the jQuery validation plugin.</p>
<p>However, there <em>are</em> a couple relatively easy workarounds that make it possible to use the jQuery validation plugin on WebForms pages, without re-architecting the page or its forms. In this post, I’ll show you <strong>why the WebForms page structure is a problem</strong>, how to <strong>make jQuery validation work with it</strong>, and <strong>an example of implementing those workarounds</strong>.</p>
<p><em>Note: I want to preface this by saying that you should never rely entirely on client-side validation. The jQuery validation plugin can be a great replacement for the client-side part of the ASP.NET Validators, but it is not a complete replacement on its own. Use responsibly!</em></p>
<h3>&lt;form&gt; over function</h3>
<p>When it comes to using jQuery validation, <strong>the trouble with WebForms is that it requires all of the ASP.NET controls on a page to be contained within a single form element</strong>. That doesn’t lead to any problems in simple demos, but things are more complicated when it comes to real-world pages. They often require multiple logical forms on the same page, and that’s where the problems start.</p>
<p>For example, consider the common scenario of having both a login form and a customer information form on the same page. We’ve probably all seen something like this before:</p>

<div class="wp_syntax"><div class="code"><pre class="asp" style="font-family:monospace;"><span style="color: #060; font-weight: bold;">&lt;</span>form id<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;form1&quot;</span> runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>
  <span style="color: #060; font-weight: bold;">&lt;</span>fieldset<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>legend<span style="color: #060; font-weight: bold;">&gt;</span>Returning customer<span style="color: #060; font-weight: bold;">?</span>  Login here<span style="color: #060; font-weight: bold;">&lt;/</span>legend<span style="color: #060; font-weight: bold;">&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Username&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Email<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Username&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Password&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Password<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Password&quot;</span> TextMode<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Password&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>Button runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Login&quot;</span> Text<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Login&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
  <span style="color: #060; font-weight: bold;">&lt;/</span>fieldset<span style="color: #060; font-weight: bold;">&gt;</span>
&nbsp;
  <span style="color: #060; font-weight: bold;">&lt;</span>fieldset id<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;BillingInfo&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>legend<span style="color: #060; font-weight: bold;">&gt;</span>New customer<span style="color: #060; font-weight: bold;">?</span>  Provide the following<span style="color: #060; font-weight: bold;">&lt;/</span>legend<span style="color: #060; font-weight: bold;">&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;FirstName&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>First Name<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;FirstName&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;LastName&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Last Name<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;LastName&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Address&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Address<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Address&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;City&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>City<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;City&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;State&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>State<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;State&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>label <span style="color: #909; font-weight: bold;">for</span><span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Zip&quot;</span><span style="color: #060; font-weight: bold;">&gt;</span>Zip<span style="color: #060; font-weight: bold;">:&lt;/</span>label<span style="color: #060; font-weight: bold;">&gt;</span>
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>TextBox runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Zip&quot;</span> CssClass<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;required&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
&nbsp;
    <span style="color: #060; font-weight: bold;">&lt;</span>asp<span style="color: #060; font-weight: bold;">:</span>Button runat<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;server&quot;</span> ID<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Order&quot;</span> Text<span style="color: #060; font-weight: bold;">=</span><span style="color: #c00;">&quot;Submit Order&quot;</span> <span style="color: #060; font-weight: bold;">/&gt;</span>
  <span style="color: #060; font-weight: bold;">&lt;/</span>fieldset<span style="color: #060; font-weight: bold;">&gt;</span>
<span style="color: #060; font-weight: bold;">&lt;/</span>form<span style="color: #060; font-weight: bold;">&gt;</span></pre></div></div>

<p>In most web frameworks, you would divide both logical forms into separate form elements, but WebForms requires both to remain joined within its single form element. This means that  <strong>clicking either of the Button controls will submit both logical forms together.</strong></p>
<p>Once applied to a form through <a href="http://docs.jquery.com/Plugins/Validation#Example" rel="nofollow" target="_blank">its default usage</a>, the jQuery validation plugin will attempt to validate all of the elements on that form <em>any time it is submitted</em>. That automation is usually handy, but it means <strong>users trying to submit our login form will be denied due to validation failing on the unrelated fields below</strong>.</p>
<p><img style="border: 1px solid #333;" src="http://encosia.com/blog/wp-content/uploads/2009/11/cross-validation-issue.jpg" width="490" height="416" /></p>
<p>Since using separate form elements containing WebForms controls isn’t realistic, we need to tackle this on the client-side and find a way to make jQuery validation more WebForms-friendly.</p>
<h3>Taming jQuery validation</h3>
<p>To remedy this problem, we first need to prevent the jQuery validation plugin from automatically triggering on every form submission. The initializer’s <strong>onsubmit</strong> property allows us to do just that:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// Initialize validation on the entire ASP.NET form</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// This prevents validation from running on every</span>
    <span style="color: #006600; font-style: italic;">//  form submission by default.</span>
    onsubmit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>That fixes our problem of the login form triggering unwanted validation in the form below, but it creates another issue. Now, <em>neither</em> of the forms will validate when submitted.</p>
<h3>Taking control with on-demand validation</h3>
<p>Instead of relying on the plugin to automatically validate form submissions, you may also use a less widely known method for triggering the validation on-demand. When added to a page, one of the new methods that jQuery validation exposes on the jQuery object is <strong>valid()</strong>.</p>
<p>When <a href="http://docs.jquery.com/Plugins/Validation/valid" rel="nofollow" target="_blank">valid()</a> is called on the jQuery object returned from selecting a “validated” form element, it will trigger validation on every field within the form and return a Boolean value indicating whether or not the form is valid.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    onsubmit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#Order&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Validate the form and retain the result.</span>
    <span style="color: #003366; font-weight: bold;">var</span> isValid <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#form1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">valid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// If the form didn't validate, prevent the</span>
    <span style="color: #006600; font-style: italic;">//  form submission.</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isValid<span style="color: #009900;">&#41;</span>
      evt.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>At first glance, this code might look incomplete to you. We care about more than just preventing form submissions when the form fails validation; we must also indicate the validation errors to the user.</p>
<p>Fortunately, <strong>the valid() method has the very useful side effect of displaying the plugin’s configured validation errors</strong> for any fields it finds to fail validation.</p>
<p>From the user’s perspective, this implementation is the same as the original one using the default usage. This method just happens to also have the added benefit of actually allowing returning users to log in.</p>
<h3>To be continued…</h3>
<p>This solution is a good start, but has (at least) two flaws.</p>
<p>First, it doesn’t handle keyboard triggered form submissions. <strong>What happens if the user hits the enter key in one of the TextBoxes</strong>?</p>
<p>Second, <strong>what if we want to also validate the login form</strong>? If validation rules are added to that form’s fields, we’ll have exactly the opposite problem as what we started with. Valid submissions in the lower form will be prevented by validation failures on the upper form.</p>
<p>For solutions to both of those problems, be sure to read my followup post: <a href="http://encosia.com/2009/11/24/asp-net-webforms-validation-groups-with-jquery-validation/">Emulate ASP.NET WebForms validation groups with jQuery validation</a>.</p>
<h3>Download the Source</h3>
<p><a href="/source/WebForms-jq-validation.zip"><img src="http://encosia.com/blog/wp-content/uploads/2009/11/download-webforms-jq-validation.png" width="492" height="46" alt="Download WebForms-jq-validation.zip" /></a></p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/asp-net-webforms-validation-groups-with-jquery-validation/' rel='bookmark' title='Emulate ASP.NET validation groups with jQuery validation'>Emulate ASP.NET validation groups with jQuery validation</a></li>
<li><a href='http://encosia.com/how-you-can-force-the-ajax-script-loader-to-use-jquery-1-4/' rel='bookmark' title='How you can force the Ajax Script Loader to use jQuery 1.4'>How you can force the Ajax Script Loader to use jQuery 1.4</a></li>
<li><a href='http://encosia.com/use-jquery-and-quicksearch-to-interactively-search-any-data/' rel='bookmark' title='Use jQuery and quickSearch to interactively search any data'>Use jQuery and quickSearch to interactively search any data</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/using-jquery-validation-with-asp-net-webforms/">Using jQuery validation with ASP.NET WebForms</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/using-jquery-validation-with-asp-net-webforms/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/using-jquery-validation-with-asp-net-webforms/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Updated: See how I used Firebug to learn jQuery</title>
		<link>http://encosia.com/updated-see-how-i-used-firebug-to-learn-jquery/</link>
		<comments>http://encosia.com/updated-see-how-i-used-firebug-to-learn-jquery/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 05:44:41 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=908</guid>
		<description><![CDATA[It was great to see all the positive responses to the screencast I recently recorded with Craig Shoemaker on how to use Firebug’s console to learn jQuery. That being my first screencast, I really appreciate all of your support. However, you almost unanimously commented that it was too difficult to read the commands typed at [...]
Related posts:<ol>
<li><a href='http://encosia.com/see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='See how I used Firebug to learn jQuery'>See how I used Firebug to learn jQuery</a></li>
<li><a href='http://encosia.com/4-aspnet-ajax-javascript-ui-functions-you-should-learn/' rel='bookmark' title='4 ASP.NET AJAX JavaScript UI methods you should learn'>4 ASP.NET AJAX JavaScript UI methods you should learn</a></li>
<li><a href='http://encosia.com/updated-your-webconfig-but-sys-is-still-undefined/' rel='bookmark' title='Updated your web.config, but Sys is still undefined?'>Updated your web.config, but Sys is still undefined?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>It was great to see all the positive responses to the screencast I recently recorded with Craig Shoemaker on how to use Firebug’s console to learn jQuery. That being my first screencast, I really appreciate all of your support.</p>
<p>However, you almost unanimously commented that it was too difficult to read the commands typed at the console, and you were right. So, Craig and I re-recorded the entire thing, paying extra attention to the legibility of the end result.</p>
<p>Craig also managed to edit the same content down to 9:59m this time, so you can watch it on YouTube if you prefer:</p>
<p><object width="492" height="389"><param name="movie" value="http://www.youtube.com/v/JB6MIV_lHI0&#038;hl=en&#038;fs=1&#038;rel=0&#038;ap=%2526fmt%3D18"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/JB6MIV_lHI0&#038;hl=en&#038;fs=1&#038;rel=0&#038;ap=%2526fmt%3D18" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="492" height="389"></embed></object></p>
<p>If the HQ version of the YouTube video still isn’t legible enough for you, <a href="http://weblogs.asp.net/craigshoemaker/archive/2009/09/18/updated-video-for-using-firebug-and-jquery-post.aspx" target="_blank">Craig also made a full resolution WMV available as well</a>.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/see-how-i-used-firebug-to-learn-jquery/' rel='bookmark' title='See how I used Firebug to learn jQuery'>See how I used Firebug to learn jQuery</a></li>
<li><a href='http://encosia.com/4-aspnet-ajax-javascript-ui-functions-you-should-learn/' rel='bookmark' title='4 ASP.NET AJAX JavaScript UI methods you should learn'>4 ASP.NET AJAX JavaScript UI methods you should learn</a></li>
<li><a href='http://encosia.com/updated-your-webconfig-but-sys-is-still-undefined/' rel='bookmark' title='Updated your web.config, but Sys is still undefined?'>Updated your web.config, but Sys is still undefined?</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/updated-see-how-i-used-firebug-to-learn-jquery/">Updated: See how I used Firebug to learn jQuery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/updated-see-how-i-used-firebug-to-learn-jquery/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/updated-see-how-i-used-firebug-to-learn-jquery/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>Get early access to ASP.NET AJAX in Action, Second Edition</title>
		<link>http://encosia.com/get-early-access-to-asp-net-ajax-in-action-second-edition/</link>
		<comments>http://encosia.com/get-early-access-to-asp-net-ajax-in-action-second-edition/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 13:17:39 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Reading]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=893</guid>
		<description><![CDATA[If you’ve been reading long, you might remember that I’ve been a fan of ASP.NET AJAX in Action since the original was published. By avoiding heavy reliance on drag ‘n drop methodologies, the Manning book leaves readers with a deeper understanding of the framework. Without understanding the underlying mechanisms well, developing successful solutions is as [...]
Related posts:<ol>
<li><a href='http://encosia.com/three-free-copies-of-aspnet-ajax-in-action-up-for-grabs/' rel='bookmark' title='Three copies of ASP.NET AJAX in Action up for grabs'>Three copies of ASP.NET AJAX in Action up for grabs</a></li>
<li><a href='http://encosia.com/three-copies-of-aspnet-ajax-in-action-still-available/' rel='bookmark' title='Three copies of ASP.NET AJAX in Action still available'>Three copies of ASP.NET AJAX in Action still available</a></li>
<li><a href='http://encosia.com/review-advanced-aspnet-ajax-server-controls/' rel='bookmark' title='Review: Advanced ASP.NET AJAX Server Controls'>Review: Advanced ASP.NET AJAX Server Controls</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://manning.com/gallo2/" target="_blank"><img src="http://encosia.com/blog/wp-content/uploads/2009/08/asp-net-ajax-in-action-2e-cover-sm.png" alt="The book cover of ASP.NET AJAX in Action, 2nd Edition" style="float: left; margin: 5px 8px 10px 0; border: 1px solid #000;" /></a>If you’ve been reading long, you might remember that <a href="http://encosia.com/2007/12/17/three-free-copies-of-aspnet-ajax-in-action-up-for-grabs/">I’ve been a fan of ASP.NET AJAX in Action since the original was published</a>. By avoiding heavy reliance on drag ‘n drop methodologies, the Manning book leaves readers with a deeper understanding of the framework.</p>
<p>Without understanding the underlying mechanisms well, developing successful solutions is as much a function of luck as it is skill; especially when it comes to debugging and maintenance. So, I think a comprehensive book like this is absolutely essential.</p>
<h3>Now with more Encosia</h3>
<p>Already being a fan of the book, you can probably imagine my response when I got an email from <a href="http://aspadvice.com/blogs/garbin/" target="_blank">Alessandro</a> asking if I’d like to participate in the Second Edition. It was certainly the easiest decision I made that day, to say the least. I’ll be helping add new examples, writing about <a href="http://encosia.com/2008/07/23/sneak-peak-aspnet-ajax-4-client-side-templating/">ASP.NET AJAX 4.0’s new features</a>, and discussion about <a href="http://encosia.com/2009/05/20/automatically-minify-and-combine-javascript-in-visual-studio/">automating things like script compression</a>.</p>
<p>Though the book is still several months away from completion, <strong>three chapters are already available</strong> via the Manning Early Access Program (MEAP) for pre-orders. In fact, one chapter of the book is freely available, so be sure to check it out.</p>
<p>For a full ToC, the MEAP, and more information about the book, head over to the <a href="http://manning.com/gallo2/" target="_blank">ASP.NET AJAX in Action, Second Edition page on Manning’s site</a>.</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/three-free-copies-of-aspnet-ajax-in-action-up-for-grabs/' rel='bookmark' title='Three copies of ASP.NET AJAX in Action up for grabs'>Three copies of ASP.NET AJAX in Action up for grabs</a></li>
<li><a href='http://encosia.com/three-copies-of-aspnet-ajax-in-action-still-available/' rel='bookmark' title='Three copies of ASP.NET AJAX in Action still available'>Three copies of ASP.NET AJAX in Action still available</a></li>
<li><a href='http://encosia.com/review-advanced-aspnet-ajax-server-controls/' rel='bookmark' title='Review: Advanced ASP.NET AJAX Server Controls'>Review: Advanced ASP.NET AJAX Server Controls</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/get-early-access-to-asp-net-ajax-in-action-second-edition/">Get early access to ASP.NET AJAX in Action, Second Edition</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/get-early-access-to-asp-net-ajax-in-action-second-edition/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/get-early-access-to-asp-net-ajax-in-action-second-edition/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Simplify calling ASP.NET AJAX services from jQuery</title>
		<link>http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/</link>
		<comments>http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 17:11:37 +0000</pubDate>
		<dc:creator>Dave Ward</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://encosia.com/?p=888</guid>
		<description><![CDATA[As jQuery’s popularity in the .NET community has risen over the past year, one recurring theme I’ve seen is the desire to refactor away the details of using it to call ASP.NET AJAX services. Whether through helper function or specialized jQuery plugin, I’ve seen numerous methods proposed and/or in use. Personally, the syntax never bothered [...]
Related posts:<ol>
<li><a href='http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/' rel='bookmark' title='jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well'>jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>As jQuery’s popularity in the .NET community has risen over the past year, one recurring theme I’ve seen is the desire to refactor away the details of using it to call ASP.NET AJAX services. Whether through helper function or specialized jQuery plugin, I’ve seen numerous methods proposed and/or in use.</p>
<p>Personally, the syntax never bothered me. The contentType parameter is ugly, but I have a Visual Studio code snippet for the $.ajax call and rarely think about it.</p>
<p>That came to an end earlier this year, when I started using dataFilter. I needed to <a href="http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/" target="_blank">isolate my code from the “.d” issue</a>, and wanted to <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/" target="_blank">take advantage of browser-native JSON parsing</a> in Firefox 3.5 and IE8, which required a bulky dataFilter.</p>
<p>Repeating that entire callback function in every $.ajax call was not acceptable. So, I was happy to learn that jQuery provides an excellent solution for consolidating settings to be used in multiple instances of $.ajax.</p>
<p>In this post, I’ll show you <strong>how to use that consolidation feature</strong>, and exactly how I am now using that to <strong>more simply call ASP.NET AJAX services with jQuery</strong>.</p>
<h3>Configuring $.ajax’s default settings</h3>
<p>Rather than wrapping the $.ajax call in a plugin or helper function, jQuery provides a built-in solution that I think is a better alternative:&#160; <a href="http://docs.jquery.com/Ajax/jQuery.ajaxSetup" target="_blank">$.ajaxSetup</a>.</p>
<p>$.ajaxSetup accepts an array of settings that allows you to supply defaults for any of the parameters that you would set in an $.ajax call. Settings like <strong>contentType</strong>, <strong>type</strong>, and <strong>dataFilter</strong> are all fair game, for example.</p>
<p>Using this function, it’s easy to set jQuery’s $.ajax defaults to match <a href="http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/" target="_blank">the refined settings that we worked out together last year</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajaxSetup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json; charset=utf-8&quot;</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;{}&quot;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Because <strong>parameters to</strong> <strong>$.ajax override these defaults</strong>, presetting “data” to an empty JSON string is safe. Any $.ajax call that does specify a data parameter will function as expected, since the default will be ignored.</p>
<p>The particular issue caused by forgetting the empty data parameter can be difficult to track down, and only shows up after you’ve deployed your application to IIS. So, having the default as a safety net is recommended.</p>
<h3>Adding JSON parsing improvements</h3>
<p>Because $.ajaxSetup also supports setting a dataFilter, adding <a href="http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/" target="_blank">the “.d” isolation</a> and <a href="http://encosia.com/2009/07/07/improving-jquery-json-performance-and-security/" target="_blank">browser-native JSON parsing</a> from my last two posts is easy:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajaxSetup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
  contentType<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json; charset=utf-8&quot;</span><span style="color: #339933;">,</span>
  data<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;{}&quot;</span><span style="color: #339933;">,</span>
  dataFilter<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> msg<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #009900;">&#40;</span>JSON<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #3366CC;">'undefined'</span> <span style="color: #339933;">&amp;&amp;</span> 
        <span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #009900;">&#40;</span>JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">'function'</span><span style="color: #009900;">&#41;</span>
      msg <span style="color: #339933;">=</span> JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">else</span>
      msg <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'('</span> <span style="color: #339933;">+</span> data <span style="color: #339933;">+</span> <span style="color: #3366CC;">')'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>msg.<span style="color: #660066;">hasOwnProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'d'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">return</span> msg.<span style="color: #660066;">d</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">else</span>
      <span style="color: #000066; font-weight: bold;">return</span> msg<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This dataFilter processing is actually what pushed me to start using $.ajaxSetup in all of my own projects. It was one thing to accept multiple contentType and method declarations, but repeating the dataFilter for every $.ajax call was more than I could handle.</p>
<h3>Putting it to work</h3>
<p>With the ASP.NET AJAX defaults set in $.ajaxSetup, <strong>all that’s required to call a “ScriptService” or page method is the URL and a success callback</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  url<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;HelloWorld.asmx/Hello&quot;</span><span style="color: #339933;">,</span>
  success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In fact, even the success callback is optional. For example, if you were periodically pinging a “heartbeat” service to keep the user’s session alive, $.ajax would only need the service&#8217;s URI.</p>
<p>This more concise syntax makes your service calls <em>far</em> more readable, especially for developers who aren’t familiar with the content-type required by ASP.NET AJAX. </p>
<h3>Caution: Sometimes it works too well</h3>
<p>While this is a handy way to simplify calls to ASP.NET AJAX services, do understand that <strong>$.ajaxSetup applies to all of jQuery’s AJAX derivatives</strong>. Setting the default HTTP method and content-type may also impact code and plugins that use jQuery’s built-in communication functionality (e.g. $.getJSON, $.post, etc).</p>
<p>For example, I often <a href="http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/" target="_blank">use jTemplates as a client-side templating solution</a>. Because its processTemplateURL routine relies on $.ajax to retrieve remote template files, setting the ASP.NET AJAX content-type and POST method in $.ajaxSetup breaks that functionality of jTemplates.</p>
<p>Fixing that problem wasn’t difficult, but it also wasn’t immediately obvious what had caused the issue in the first place. In my experience using this technique, the undesirable side effects are rare enough that it’s not a serious concern, but do be aware of the potential.</p>
<h3>Conclusion</h3>
<p>I’ve been using this in production for several months now, with great results. Users have noticed the increased speed that came with browser-native JSON parsing, the “.d” isolation has reduced regression errors due to some code we run on both 2.0 and 3.5 servers, and <strong>it requires less effort on my part to do all that</strong>.</p>
<p>What do you think? Is this helpful?</p>
<p>Would a Visual Studio template with this rolled in be something you would use?</p>
<p>Related posts:<ol>
<li><a href='http://encosia.com/jquery-1-5s-ajax-rewrite-and-asp-net-services-all-is-well/' rel='bookmark' title='jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well'>jQuery 1.5&#8242;s AJAX rewrite and ASP.NET services: All is well</a></li>
<li><a href='http://encosia.com/using-complex-types-to-make-calling-services-less-complex/' rel='bookmark' title='Using complex types to make calling services less&#8230; complex'>Using complex types to make calling services less&#8230; complex</a></li>
<li><a href='http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/' rel='bookmark' title='Using jQuery to Consume ASP.NET JSON Web Services'>Using jQuery to Consume ASP.NET JSON Web Services</a></li>
</ol></p><hr />

<p>You've been reading <a href="http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/">Simplify calling ASP.NET AJAX services from jQuery</a>, originally posted at <a href="http://encosia.com">Encosia</a>.  I hope you enjoyed it, and thanks for reading.</p>

<p>If you've got any feedback, please click through and leave a comment; I'd love to hear from you. You can <a href="http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/#post-commentblock">click here to jump directly to the comment section of this post</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://encosia.com/simplify-calling-asp-net-ajax-services-from-jquery/feed/</wfw:commentRss>
		<slash:comments>88</slash:comments>
		</item>
	</channel>
</rss>

