Monday, December 29, 2008

How to call a web service from jquery passing json data

Ok, so today I was finally able to rewrite all the asynchronous webservice calls with jquery using JSON for passing data from JQuery to Webservice (or is it Web service?) and getting result back from Webservice to jquery. For those who don't know whats going on, here's a little background info - As I noted in my previous posts, RSH (Really Simple History) uses JSON quite a bit and JSON doesn't seem to play well with Microsoft ASP.NET Ajax's (or Ajax.net if you prefer) ScriptManager control and I was using ScriptManager control to access my webservices from javascript (JQuery). Today, I finally figured out the best (or atleast easiest) way of calling webservice methods from jquery and using JSON for passing data (webservice's webmethod's arguments) to the webservice and getting the result back to jquery (result of the webmethod's call, yeah i'm verbose!).

And as you'd expect, it made a hell lot of difference in performance! Now when I compare the approach of using a Webservice via a ScriptManager with this approach of calling the Webmethod directly via jquery, the performance improvement in the webservice calls are ridiculous! This is to be expected though as ASP.NET's Ajax ScriptManager generates a slew of helper client side scripts that totally bog the system down...err..ok not totally but the Webservice calls through ScriptManager do seem to add some kilobytes (can be over 100kb too) of extra code. Obviously, the jquery webservice calls implementation comes with it's own overhead too but I personally think that the jquery's overhead are not really deal breaker if you plan to write some little jquery helper functions yourself for making webservice calls. Besides the little fact that since the direct jquery with json webservice calls thingy doesn't require a ScriptManager, you can do it in any language - asp.net, php, ruby, c, assembly....err not assembly I guess...but you get the picture!

Anyhow, enough of my babbling, lets get on to the good stuff...some sample code to show how to go about calling a webservice from jquery (clientside, javascript whatever) via a ScriptManager (ASP.net ajax) and directly from jquery (again clientside, javascript whatever) using json -

How to call a Webservice from jquery using ScriptManager -



1. Import using System.Web.Script namespace and add ScriptService attribute to your webservice class. For example -


using System.Web.Script;
[ScriptService]
public class OurPotentiallySlowWebService: System.Web.Services.WebService


2. Add WebMethod and ScriptMethod attributes to your web-methods that need to be called from javascript/jquery/clientside/mars....ok not mars. Example -


[WebMethod, ScriptMethod]
public string SaveThisDataComingFromJQuery(string data1, data2)


3. Add the following ScriptManager tag at the top of your form

<asp:ScriptManager runat="server" EnablePageMethods="true" ID="BlahScriptManager"
EnableHistory="true" EnablePartialRendering="true" EnableStateHash="false" OnNavigate="BlahScriptManager_Navigate">
<Services>
<asp:ServiceReference Path="~/OurPotentiallySlowWebService.asmx" />
</Services>
</asp:ScriptManager>

4. Call the SaveThisDataComingFromJQuery method from your javascript -

var finallyIGotResult = OurPotentiallySlowWebService.SaveThisDataComingFromJQuery ("datavalue1", "datavalue2");

Yes, that was it! ASP.NET Ajax ScriptManager has simplified the seemingly complex webservice call to ridiculous levels! But as I said, it came at a great cost of many extra kilobytes that might potentially slow your webpage down giving your visitor to hit back button and find some faster and more response website than yours! But fear not, you can do whatever that faster website did to become faster and stay in the game, read on....

How to call Webservices from jquery and use JSON to pass data back and forth -



(First 2 steps will remain the same as above but I've reproduced them below too just in case you knew the folly of ASP.net's ScriptManager and skipped the above section)

1. Import using System.Web.Script namespace and add ScriptService attribute to your webservice class. For example -

using System.Web.Script;
[ScriptService]
public class OurFastestWebService: System.Web.Services.WebService

2. Add WebMethod and ScriptMethod attributes to your web-methods that need to be called from javascript/jquery/clientside/mars....ok not mars. Example -

[WebMethod, ScriptMethod]
public string SaveThisDataComingFromJQuery(string data1, data2)

3. Here the fun starts, you call the webmethod with the $.ajax method that totally rocks! Example -

$.ajax({
type: "POST",
url: "OurFastestWebService.asmx/SaveThisDataComingFromJQuery",
data: "{'data1':'datavalue1','data2':'datavalue1'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) { var iGotResultAndPageisFaster = msg.d; }
error: function(err) { alert('you don't deserve to write code'); }
});

Holy sh-t! What's that "thing" above! Fear not, the good news is that the bolded part on the right of colons is the only stuff you will change most of the time, still I take this piece of code apart below -

$.ajax({ -> This is the name of the jquery method. The little "{" at the end just means that we are sending the parameters / arguments to $.ajax in JSON format. JSON format is basically - {field1:value1, field2:value2}. JSON is a beauty in itself and I might write about it's advance usage later on but I hope you got the basic idea here.

data -> This is just the list of arguments and their values. Thing to keep in mind is that the the argument names here must match with the argument names used in the WebMethod. As you can see, I've used 'data1' and 'data2' both here and in SaveThisDataComingFromJQuery WebMethod.

Rest of the options are kinda self explanatory and won't change so I won't comment on them and seriously you should just make it work and go hit some clubs or something...but if you are married then you may visit http://docs.jquery.com/Ajax/jQuery.ajax#toptions for a fuller list of options.

Yeah, it was *that* easy! So you see that, even if the ASP.net Ajax ScriptManager does help add some code on our behalf the webservice call easier but the difference is not *that* big even with Ajax. And if you add a helper method then even that little difference is eliminated.

How to write a helper method for making $.Ajax calls to webservice -

function iWannaCallMyFastestWebService(datavalue1, datavalue2)
{
$.ajax({
type: "POST",
url: "OurFastestWebService.asmx/SaveThisDataComingFromJQuery",
data: "{'data1':'datavalue1','data2':'datavalue1'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) { var iGotResultAndPageisFaster = msg.d; }
error: function(err) { alert('you don't deserve to write code'); }
});
}

Now you can call this method everywhere and bingo, you've just eliminated the need (and overhead) of ScriptManager, ASP.net Ajax, Ajax.net, Microsoft, Global Warming, completely.....ok not Global Warming but you got the point. Now let's compare the two method calls -

function iFunWithFastestWebservice()
{
iWannaCallMyFastestWebService("yoyo1", "yoyo2");
OurPotentiallySlowWebService.SaveThisDataComingFromJQuery ("datavalue1", "datavalue2");
}

Holy christ! It looks as if our jquery approach even saves some precious space for web service calls! So, now you the truth! Let the force be on your side, happy coding!

1 comment: