Using jQuery to Consume ASP.NET JSON Web ServicesEncosia

In response to many of the articles here, I receive feedback asking how to achieve the same results without using ASP.NET AJAX. As much as I’m a fan of ASP.NET AJAX, I must agree that its JavaScript payload can certainly be a drawback in some situations.

My recent deferred content loading post is an excellent example of that. I was using jQuery for presentational effects, and using a ScriptManager to call a web service. Loading the JavaScript for both frameworks was a bit counterproductive, since the whole point was to improve initial load time.

In this post, I intend to correct that.

First, I’ll cover the two requirements necessary when calling an ASMX web service that’s being JSON serialized by the ASP.NET AJAX extensions. Then, I’ll show you how to do this with jQuery. Finally, I’ll update the deferred content loading example accordingly.

Additional security when calling JSON serialized services

A security feature of ASP.NET web services that are JSON serialized through the ASP.NET AJAX extensions is that they must be requested in a specific way. This is an important deterrent against your services being used in XSS attacks. Scott Guthrie has a great post providing detailed information on the particulars. It boils down to is two things:

  • The request must be an HTTP POST request
  • The request’s content-type must be: “application/json; charset=utf-8″

When you register and call a web service through ASP.NET AJAX’s ScriptManager, you may safely enjoy blissful ignorance of these requirements. The framework transparently handles everything for you.

However, if you want to use a third party AJAX framework to request the JSON serialized output, you may run into trouble due to these security features.

How to make jQuery jump through these hoops

The solution is a bit less intuitive than using the ScriptManager or what you would normally expect from jQuery. Using jQuery’s getJSON() would make sense, but it unfortunately meets neither of the above security criteria.

The most reliable way that I’ve found is to use jQuery.ajax() as follows:

$.ajax({   type: "POST",   url: "WebService.asmx/WebMethodName",   beforeSend: function(xhr) {     xhr.setRequestHeader("Content-type",                          "application/json; charset=utf-8");   },   dataType: "json" });

Setting the request type to POST is self explanatory.

The beforeSend option is the key. It allows you to handle a jQuery event very similar to the PageRequestManager’s InitializeRequest event. The function is called with a reference to the actual XmlHttpRequest object about to be used in the AJAX call. This allows us to set its content-type to what the ASP.NET AJAX framework requires, just before the request is made.

Note: jQuery.ajax() does have a contentType option, but it will be ignored if there is no data included in the POST. For read-only requests, this will cause the call to unexpectedly fail. To maintain consistent usage across implementations, I prefer to always set it up explicitly with the beforeSend event handler.

Putting it all together

Now that we know how to call the web service, appropriately modifying the original example is easy. Here’s the new ASPX code:

<div id="Container">   <div id="RSSBlock">     <div id="RSSContent" class="loading"></div>   </div>    <div id="Content">     <p>Lorem ipsum dolor sit amet, consectetuer adipiscing...</p>   </div> </div> </form>  <script type="text/javascript" src="jquery-1.2.3.min.js"></script> <script type="text/javascript" src="Default.js"></script>

Notice that I’ve placed the JavaScript references below the rest of the page’s content. Since browsers block while requesting, loading, and executing JavaScript, it makes sense to defer that until as late as possible. This will serve to further boost the page’s perceived performance.

Finally, the jQuery code to call the web service and appropriately handle its result:

$(document).ready(function() {   $.ajax({     type: "POST",     url: "RSSReader.asmx/GetRSSReader",     beforeSend: function(xhr) {       xhr.setRequestHeader("Content-type",                            "application/json; charset=utf-8");     },     dataType: "json",     success: function(msg) {       // Hide the fake progress indicator graphic.       $('#RSSContent').removeClass('loading');        // Insert the returned HTML into the <div>.       $('#RSSContent').html(msg.d);     }   }); });

Conclusion: Is it worth it?

By using jQuery to call the web service directly, we’ve eliminated over 100 KB of JavaScript and three extra HTTP requests. The ASP.NET AJAX client side framework accounted for over half of the original example’s total download size, and those three extra HTTP requests unnecessarily delayed the progress indicator.

That may not sound like much, but it’s significant. When it comes to loading speed and responsiveness, users do not perceive changes linearly. Fractions of a second make the difference between a site that feels sluggish and one that appears responsive.

A word about web services

Web services are great tools that afford you substantial flexibility. It’s important not to overlook them.

You’ve no doubt seen many AJAX examples that involve using the XmlHttpRequest to request the output of a specially designed page, resulting in CSV or otherwise arbitrarily formatted data instead of HTML. For instance, I’ve noticed that a lot of the auto-complete plugins for jQuery expect this sort of kludge.

I believe that to be a short-sighted and counterproductive way to do things.

Web services have often been maligned in the past, due to the XML bloat associated with SOAP. However, JSON makes this drawback a thing of the past. JSON is very lightweight, making it ideal for structured AJAX communication. With the inefficiencies of SOAP neutralized, I think the power and flexibility of web services cannot be overstated.

For example, if I decide to move my sites from WebForms to MVC, there is a large amount of functionality encapsulated in web services that I won’t have to worry about recoding or redesigning. It’s a great feeling to have that flexibility and ease of reuse.

When used well, I think web services are to WebForms what object oriented programming was to procedural and functional programming.

Try it for yourself: download the source

The full example’s source code (ASP.NET 3.5 required):

Download source: (33kb)

Originally posted at: Encosia.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

WP Like Button Plugin by Free WordPress Templates