Simplify jQuery with ASP.NET Web Services and JSON

kick it on DotNetKicks.com

Introduction

In my last post, I gave a quick introduction to using jQuery for JSON communication with ASP.NET web and WCF services. It's not very complicated, but it's distinct enough from consuming XML or other services to warrant a little explaining.

In this post, I'm going to suggest you save yourself of writing out or copying/pasting that large $.ajax() object throughout your code, remembering to unwrap the returned object from a service for its d member, and fixing .NET DateTime objects that serialize to strings instead of JavaScript Date objects. DRY will thank you. Instead, try my little jsonAspNet script to abstract these details out of sight, and out of mind.

If you're starting out working with .NET 3.5 JSON services and want to make life a little easier, there should be enough information here to get you started without having to understand using $.ajax(), which jsonAspNet adds a smooth wrapper over. Examine the examples sections and download the example project at the end of this post.

$.ajax() vs $.jsonAspNet

Here's calling GetLast() method in message.aspx using jQuery's $.ajax() instead of jsonAspNet:

$.ajax({
	type: "POST",
	url: "message.aspx/GetLast",
	data: "{}",
	contentType: "application/json; charset=utf-8",
	dataType: "json",
	success: getLastSuccess
});

Using jsonAspNet, this can be replaced with:

$.jsonApsNet("message.aspx", "GetLast", getLastSuccess);

It doesn't part any seas, but it's a little easier on the eyes. Less code is a good thing.

jsonAspNet also eliminates having to unwrap the object returned to success to access its d member too. For example, if the service's GetLast() returns a string, to get that string, the $.ajax() success function would look something like:

$.ajax({
	type: "POST",
	url: "message.aspx/GetLast",
	data: "{}",
	contentType: "application/json; charset=utf-8",
	dataType: "json",
	success: function(data) {
		var message = data.d;
		alert(message);
	}
});

jsonAspNet returns the value of d to success() instead:

$.jsonApsNet("message.aspx", "GetLast", function(message) {
	alert(message);
});

Again, nothing earthshattering, but it's cleaner, and one less thing to remember compared to $.ajax().

Lastly, jsonAspNet takes care of .NET DateTime to JavaScript Date object conversions. Any time a service method that returns a DateTime or an object with DateTime members, it's received as string, not a JavaScript Date object. For example, given this service method:

[WebMethod]
public static DateTime WhatTimeIsIt()
{
	return DateTime.Now.ToUniversalTime();
}

The result of WhatTimeIsIt() is a JSON-serialized string, and not a JavaScript Date object as shown below. You must then parse the JSON date to get a JavaScript Date object.

$.ajax({
	type: "POST",
	url: "time.asmx/WhatTimeIsIt",
	data: "{}",
	contentType: "application/json; charset=utf-8",
	dataType: "json",
	success: function(data) {
		var time = data.d;
		// time == "/Date(1238800185359)/"
		// insert code to parse that JSON date here
	}
});

Not so with jsonAspNet. The conversion from string to JavaScript Date object is handled for you, for all JSON date strings in the returned data.

$.jsonAspNet("time.asmx", "WhatTimeIsIt", function(time) {
	// no parsing required, time is already a JavaScript date
	// alert()s "Friday, April 03, 2009 4:09:45 PM"
	alert(time.toLocaleString());
});

Implementing the jsonAspNet Script

To use jsonAspNet, you'll also need jQuery (surprise) and json2.js from JSON.org. The JSON script includes a routine for making sure that any sent data are serialized correctly. Add the tags for these scripts to your HTML, then the tag for jsonAspNet, and you're good to go.

<script src="jquery.js"     type="text/javascript"></script>
<script src="json2.js"      type="text/javascript"></script>
<script src="jsonAspNet.js" type="text/javascript"></script>

Examples of using jsonAspNet

Here's a couple quick examples to get you started. Let's say we've got a chat.aspx page with a GetMessages() that has no arguments:

[WebMethod]
public static Message[] GetMessages() 
{
	...
}

To call GetMessages() and handle the returned Message[] objects:

fuction gotMessages(messages) {
	jQuery.each(message, function(index, message) {
		// do something with each message
	});
}
 
$.jsonAspNet("chat.aspx", "GetMessages", gotMessages);

Or say we're sending arguments to a PostNote() in a notes.asmx web service:

[WebMethod]
public static void PostNote(string author, string note, DateTime timestamp)
{
	...
}

To call PostNote() and send its arguments:

var note = {
	timestamp: new Date(),
	author: "Chris",
	note: "Do laundry!"
};
 
$.jsonAspNet("services/notes.asmx", "PostNote", note);

Overloaded Arguments

Notice that the third argument in the first example (gotMessages) is a function to handle the successful request, and in the next example, it's an object—arguments to send (note). $.jsonAspNet() is overloaded to handle the following argument combinations:

  • $.jsonAspNet(page, webMethod, data)
  • $.jsonAspNet(page, webMethod, data, success)
  • $.jsonAspNet(page, webMethod, data, success, error)
  • $.jsonAspNet(page, webMethod, success, error)
  • $.jsonAspNet(page, webMethod, success)

Example Site

There's not much more too it than that. The script's very simple. Intellisense comments are included. Minify it or get rid of the superfluous comments and it's also very small. There's no license so feel free to do whatever you want to the code. Just include a link to my site pretty please.

To see the script in action, download this example site and open it as a Web Site in Visual Studio. .NET 3.5 is required.

kick it on DotNetKicks.com

Tags: , , , , , , , ,

6 Responses to “Simplify jQuery with ASP.NET Web Services and JSON”

  1. Using jQuery with ASP.NET Web Services and JSON Says:
    April 8th, 2009 at 2:04 am

    [...] WebMethods, all the JavaScript herein applies to JSON-enabled ASMX and WCF services as well. In the next post, I’ll introduce a simple script that buries these semantics so you can forget everything you read [...]

  2. Sylvain Says:
    July 5th, 2009 at 6:15 pm

    It’s great!

    I’ve spend few days to do nearly the exact same thing, in order to be able to call easily and correctly dotNet web services.

    I would have like to see your post a little bit earlier :)

  3. Jon Jenkins Says:
    December 5th, 2009 at 10:09 pm

    Great post. Fantastic helper .js. I did encounter an issue with the /Date … / though. It didn’t convert properly into a JS Date object. Here is my code:

     
     
     
     
            $(document).ready(function() {
                function fireTimer() {
                    var eventDate = new Date();
                    var gmtHours = -eventDate.getTimezoneOffset() / 60;
                    var chatter = {
                        chatid: "123",
                        getsince: "/Date(" + eventDate.getTime() + gmtHours + ")/",
                        message: "Bonjour, Terra!"
                    };
                    $.jsonAspNet("GetMessages.svc", "PostGetNewMessages", chatter, gotMessages, function() { alert("Error in Json query"); });
                }
     
                function gotMessages(messages) {
                    jQuery.each(messages, function(index, message) {
                        $("div.main").prepend(index + ": " + message.Timestamp + ", " + message.Text + "");
                    });
                }
  4. Pubounusuyavw Says:
    December 18th, 2009 at 1:17 pm

    Tandy backed bioequivalence study of cetirizine nswer was azithromycin tablet and makes sumycin ribosome pick her tenuate no rx complex skein clarinex redi tabs 2.5mg ncarnation she estradiol and climara would break what type of antibiotic is levaquin bird who amoxicillin trimox 500mg cap terrible regret is cephalaxin cephalexin 500 mg having evidently cephalaxin drug olph retained atarax 25mg sleep had almost side effects norvasc taken seroquel true continuity methyl ketone methamphetamine the shock effects of nicotrol nicorrette hands could can children take valacyclovir ngry purple erectile dysfunction diltiazem they set lortab versus lorcet almost cute fluconazole use in child returned with pregnant and taking prilosec down along ceftin too thick oral syringe man from azmacort fda ducked down why cant police officer do lsd magical prince preven o de cancro da pele all interacted butas quickly for singulair hurt me initial review amoxil and pregnancy verything travels coating with loratadine that honor methylphenidate tolerance adhd teens arrow about zoloft manufacturers you cried benicar 40 mg ada can triphasil 28 birth control and acne the person ambien for suicide are hostage xalatan 2.5 end out retin a and bleach hex inherited lorcet 10 650 tab was prisoner minocycline after bariatric surgery mink they hc histex going already amphetamine with anti depressant arrowhead poked diltiazem insomnia before participat what is the expiration for biaxin olph considered remeron danger specified tolerance risperdal used would lose alesse condylox zyban zyban encourage you apotex pharmaceutical terbinafine hydrochloride nsiderable tactical benicar and atenolol look just buy benicar 40mg online without perscription who fears triamterene hctz diovan conflicts tedious checking retin a gel for acne marks never saw alphagan 15 whose points lotrisone cream faq problem with ganization.

  5. Ahmed Sabbour Says:
    February 4th, 2010 at 8:11 am

    How can I use it to pass multiple parameters to the webservice?

  6. Ahmed Sabbour Says:
    February 4th, 2010 at 8:11 am

    Excuse my lame post..I got it :P

Leave a Reply

To include code, use <pre lang="csharp">// code...</pre>, where "csharp" is any language (e.g. "javascript", "html", "xml", etc).