Using jQuery to directly call ASP.NET AJAX page methods
AJAX, ASP.NET, JavaScript, jQuery By Dave Ward on May 29th, 2008When it comes to lightweight client-side communication, I’ve noticed that many of you prefer ASP.NET AJAX’s page methods to full ASMX web services. In fact, page methods came up in the very first comment on my article about using jQuery to consume ASMX web services.
Given their popularity, I’d like to give them their due attention. As a result of Justin’s question in those comments, I discovered that you can call page methods via jQuery. In fact, it turns out that you can even do it without involving the ScriptManager at all.
In this post, I will clarify exactly what is and isn’t necessary in order to use page methods. Then, I’ll show you how to use jQuery to call a page method without using the ScriptManager.
Creating a page method for testing purposes.
Writing a page method is easy. They must be declared as static, and they must be decorated with the [WebMethod] attribute. Beyond that, ASP.NET AJAX takes care of the rest on the server side.
This will be our page method for the example:
public partial class _Default : Page { [WebMethod] public static string GetDate() { return DateTime.Now.ToString(); } }
What about the ScriptManager and EnablePageMethods?
Traditionally, one of your first steps when utilizing page methods is to set the ScriptManager’s EnablePageMethods property to true.
Luckily, that property is a bit of a misnomer. It doesn’t enable page methods at all, but simply generates an inline JavaScript proxy for all of the appropriate methods in your page’s code-behind.
For example, if a ScriptManager is added to the above example’s corresponding Default.aspx and its EnablePageMethods property is set to true, this JavaScript will be injected into the page:
var PageMethods = function() { PageMethods.initializeBase(this); this._timeout = 0; this._userContext = null; this._succeeded = null; this._failed = null; } PageMethods.prototype = { _get_path:function() { var p = this.get_path(); if (p) return p; else return PageMethods._staticInstance.get_path();}, GetDate:function(succeededCallback, failedCallback, userContext) { return this._invoke(this._get_path(), 'GetDate',false,{}, succeededCallback,failedCallback,userContext); }} PageMethods.registerClass('PageMethods',Sys.Net.WebServiceProxy); PageMethods._staticInstance = new PageMethods(); // Generic initialization code omitted for brevity. PageMethods.set_path("/jQuery-Page-Method/Default.aspx"); PageMethods.GetDate = function(onSuccess,onFailed,userContext) { PageMethods._staticInstance.GetDate(onSuccess,onFailed,userContext); }
Don’t worry if you don’t understand this code. You don’t need to understand how it works. Just understand that this JavaScript proxy is what allows you to call page methods via the PageMethods.MethodName syntax.
The important takeaway here is that the PageMethods proxy object boils down to a fancy wrapper for a regular ASP.NET service call.
Calling the page method with jQuery instead.
Knowing that a page method is consumed in the same way as a web service, consuming it with jQuery isn’t difficult. For more detailed information, see my previous article about making jQuery work with ASP.NET AJAX’s JSON serialized web services.
Using the jQuery.ajax method, this is all there is to it:
$.ajax({ type: "POST", url: "PageName.aspx/MethodName", data: "{}", contentType: "application/json; charset=utf-8", dataType: "json", success: function(msg) { // Do something interesting here. } });
Putting it all together.
Corresponding to the example page method above, here’s our Default.aspx:
<html> <head> <title>Calling a page method with jQuery</title> <script type="text/javascript" src="jquery-1.2.6.min.js"></script> <script type="text/javascript" src="Default.js"></script> </head> <body> <div id="Result">Click here for the time.</div> </body> </html>
As you can see, there’s no ScriptManager required, much less EnablePageMethods.
As referenced in Default.aspx, this is Default.js:
$(document).ready(function() { // Add the page method call as an onclick handler for the div. $("#Result").click(function() { $.ajax({ type: "POST", url: "Default.aspx/GetDate", data: "{}", contentType: "application/json; charset=utf-8", dataType: "json", success: function(msg) { // Replace the div's content with the page method's return. $("#Result").text(msg.d); } }); }); });
The end result is that when our result div is clicked, jQuery makes an AJAX call to the GetDate page method and replaces the div’s text with its result.
Conclusion
Page methods are much more openly accessible than it may seem at first. The relative unimportance of EnablePageMethods is a nice surprise.
To demonstrate the mechanism with minimal complications, this example has purposely been a minimal one. If you’d like to see a real-world example, take a look at Moses’ great example of using this technique to implement a master-detail drill down in a GridView.
If you’re already using the ScriptManager for other purposes, there’s no harm in using its JavaScript proxy to call your page methods. However, if you aren’t using a ScriptManager or have already included jQuery on your page, I think it makes sense to use the more efficient jQuery method.
Similar posts
What do you think? Your comments are welcomed.
I appreciate all of your comments, questions, and other feedback, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums. If you post there and then contact me with a link to the post, I'll try to take a look at it for you.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this comment" link underneath the comment you're replying to.

Comments
Nice article Dave, going to play around with this and see where its limits are.
Hi, How I can pass parameters using this method?
For Example with this function:
You can add a data parameter to the $.ajax call. You’ll find some examples in the comments on the previous post about calling web services with jQuery.
You can find the official documentation on $.ajax here: http://docs.jquery.com/Ajax/jQuery.ajax#options
I’m getting the same error Moses has a note on in his blog entry, where the “Content-Length” header is not being sent by Firefox 2.0.0.14. The exact error response is “Length Required”. His fix was to add the xhr.setRequestHeader(”Content-Length”, 0); type line to the beforeSend() function, but this still does not work for me - the header is not being sent according to Firebug. IE6/IE7/Opera/Safari work fine… tried with jQuery 1.2.6 and 1.2.3. Anyone else?
Erm, after an hour of scratching my head, I found the solution. I had to specify: data: “” in my $.ajax() call. Passing null or leaving that parameter out causes Firefox to leave out the content-length header. Hope this saves someone else some time.
Interesting. Thanks for the update, Ryan.
What server environment were you getting that error from? I’ve tested with Cassini and IIS7 with no trouble. I’d like to narrow down what circumstances the content-length becomes a problem in.
IIS6 on Windows Server 2003. That is interesting… I also tested with both Cassini and IIS5.1 and they didn’t have a problem.
Check out these links: http://forums.iis.net/p/1119456/1744358.aspx
http://objectmix.com/inetserver/284636-windows-2003-iis-server-not-responding-correctly-post.html
They seem to indicate that neither IIS6 or 7 would work without the Content-Length header unless the Transfer-Encoding: chunked header was present. Did you have that in your IIS7 test?
After testing across more server types, it looks like the best usage is this:
Since there’s POST data now, manually setting the content-type isn’t necessary. So, I think that’s cleaner anyway.
I’m going to update the two applicable posts to reflect that usage. Thanks for the feedback, Ryan.
Excellent article. I started to play with jQuery recently and I am very interesting in how to integrate it with ASP.NET. And this is more than useful!
Man, this is a great approach since ASP.NET AJAX and it’s poor performance isn’t a viable solution for many sites.
Great technique, but I don’t currently have the liberty to add in another library like JQuery. Currently I only have the .Net Ajax library. Could you please transalate this method into using the Sys.Net.WebRequest Class of the Ajax library (http://msdn.microsoft.com/en-us/library/bb310979.aspx)?
If you already have a ScriptManager on the page, you could use the EnablePageMethods property to generate the JavaScript proxy. There’s no need to manually call the page method with WebRequest in that scenario.
Thanks, but actually I originally had PageMethods js syntax for the calls….worked great, but our framework requires a level of authentication in an HTTP module that checks a GUID in either the Request.QueryString or Request.Forms.
I delved into behind-the-scenes proxy code generated, but the GUID in the querystring is gone(url is filename.aspx/GetMethod. It seems that the abstraction resulting from the proxy code of PageMethods has taken away the ability for me to get it in there, at least from what I can see so far. I believe it was said that the proxy code makes 3 calls..??
Update: works in small app with js sitting on same .aspx file, but not on real app with js in dif directory. Would this matter?
Works (small app):
Doesn’t hit (code-behind):
Sorry about being verbose. Thanks again.
Try an absolute path for set_url(), to make sure the location of your js include isn’t causing trouble.
Also, I’m assuming it is in your code, but make sure that last line of the non-working js is:
What you posted is missing the parens.
Other than that, are you getting any JavaScript errors at all, or is it failing silently?
Yes! It was missing the parens… funny the browser would just run through the code past it as if nothing was wrong, no syntax error. Here is my complete solution for anyone else it might help. It makes uses of Asp .Net Ajax library versus JQuery.
Thanks again for your help, love these articles.
Does this work with ASP.NET 2.0. Been trying to get it working but having a bit of a hard time.
As long as you have the ASP.NET AJAX extensions installed, yes.
I found the problem….apparently i can’t have a static method called test. Just doesn’t work. Test works but all lower does not work and returns a ‘parsererror’ error. Weird. very weird. Any ideas??
Not sure about that one. I’m able to declare this:
Without any errors.
How about clientcallback from Jquery implementing Icallbackeventhandler, that way we can use it on controls!!!.
The problem I have with ICallback is that it sends the ViewState in the callback. At that point, you’re almost back to the inefficiency of the UpdatePanel.
This was all working great for me, until today :(
Unfortunately, it all seems to fall down under Firefox 3, and I am having one heck of a time trying to find out why :(
Hey Dave, I I have a question, Someone asked me about this:
In my sample I just uset $(…).html(msg); while us use $(…).html(msg.d);
My sample works fine, and your sample too, But the guy told me that mind didn’t work for him, and when her replaced msg with msg.d as in your sample it worked fine!
Could you please clarify to what does “d” refers to! because I review the jQuery.Ajax Documentation for success and failure handlers and reached nothing.
Thank you Dave
The reason for the difference is that the “d” was added in ASP.NET 3.5. Running the same piece of code on 2.0 and 3.5, you’ll get the straight return in 2.0 and the “.d” type return in 3.5.
It’s my understanding that the reason for this is that forcing the result into a JSON array helps prevent potential XSS attacks.
I am using VB.NET and I cannot access my wet method. I tried making my method Public, Shared and no luck. Any
Suggestions for us VB.NET guys (I hope not to get bashed here)?
The VB equivalent should be something like this:
Wow, I just re-read my post from yesterday “I am using VB.NET and I cannot access my wet method…”. Wet Method? Hilarious! Thanks Dave, that worked perfectly. Loving JQuery!
Hi,
I can not make webmethod call with jquery work in vb.net. If do the same thing from c# it works fine. been pulling my hair. help me.
here’s my vb webmethod
here’s my javascript
and here is my HTML
it just doesnot work in vb. am i missing anything. help me
What’s it actually doing? Are the contents of the div changing at all?
I’d take a look at it in FireBug’s console and check out the request and response.
hey dave,
nope the content is not changing at all.
have FF3 and wont support firebug. but i checked the response from fiddler, it shows the whole page.
any idea why it is doing that?
FireBug 1.2 works on FireFox 3.
In my experience, what you’re seeing usually happens when the content type isn’t correct or the request isn’t a POST. I see that’s correct in your jQuery call, but double check all the specifics of the request headers in FireBug.
well i figured out what the problem was. had nothing to do with vb.net or jquery. i thought if not jquery, lemme try that with scriptmanager, but couldnt get scriptmanager on the page. turns out the .net 2.0 site i was working on was not ajax enabled. made it ajax enabled site and BAM!!! everything back to normal.
sometimes what you think the culprit is may not be the real culprit. :)
ohh in .net 2.0 msg.d wont work. it;s just msg
btw love your articles. keep on the good work.
thanks
I’ve just found that this method will only work if you’re PageMethods are in code-behind, it doesn’t work when they are part of the aspx.
ASP.NET AJAX PageMethods however, work in both.
Dave,
Thanks for posting this, it got me started on what I was trying to do.
My next task is somehow generating a proxy script for these webmethods, but uses the jquery ajax functions rather than asp.net ajax. Any ideas on how to do this?
Thanks!
Just a quick question because I couldn’t think of a better place to post this….
We’ve been using ashx handlers on the server side to supply jQuery with JSON formatted data for some time. Everybody else seems to use page methods which I assumed would have an extra overhead.
I must be wrong but can anybody explain why page methods (or even web services) are more suited to this than a handler?
I’m not aware of specific data on how their performance compares, but I think all three are probably very similar. Maybe some heavy testing is in order.
For me, one nice thing about web services and page methods is that they automatically handle the JSON serialization.
It would be interesting to know if anybody has done that actually.
I assume (from my very limited asp.net knowledge) that a .aspx page would have the extra overhead of the page life cycle (init, preinit etc.) whereas an http handler doesn’t need to do any of that?
I do know that the Page isn’t fully instantiated for a page method call (if at all). For all intents and purposes, page method calls are identical to web service calls. I haven’t noticed any performance differences between those two at all.
Page methods definitely don’t have the overhead of something like a partial postback, where the entire Page is re-instantiated.
I might run some tests and make a post of it sometime soon. It would be good to know for sure.
Hey Dave! Nice article, I’ve been benefitting from alot of your jQuery posts lately. I recently decided it was time to start looking into jQuery and thus far I totally love it. It’s concise and makes the ASP.NET AJAX framework seem so bloated and obliquitous.
Anyways, I’ve been having some problems with making POSTS from jQuery to an ASP.NET page. I am unable to retrieve the data from the Request.Params collection in my Page_Load code-behind. I have a .aspx page that has a main task of sending emails programmatically. I want to be able to POST to this page from a contact form on another page via jQuery (the plan is to have a brief contact form on every single page, and a bigger contact form on this main contact page where they can attach files to the message as well [which is why I am posting to a page instead of a handler]). I will get to the big contact form later, but first I need the small forms to work. If I change my JS to use the GET method, it works perfectly. But I’m going to need to make POST work for the file uploads. Is there anything obvious I am missing here? I am using the jQuery Ajax serialize() function to transform the user input into legitimate POST parameters, but I can not seem to receive any of the data on the server-side.
Getting frustrated. Hope you can help!
I like your blog, by the way.
Best regards…
I have used jQuery and Ajax for my site and it works great. I had a look at dojo but jQuery is I think sampler and easier. I like the integration with flash too.
Great post thanks.
I’m looking to switch from Ajax.NET Pro to jQuery and this solution helps. However, I have quite a few helper classes in my App_Code folder that provide methods for Ajax calls. How would they be referenced in the jQuery.ajax url parameter when there is no .aspx page?
I also have custom controls that are compiled separately and included in the project. How would methods in the control DLL be referenced?
I’m not aware of any way to directly access arbitrary methods and properties of classes that aren’t exposed by a page method or web service. The usual solution is to create web services to act as proxy to that business logic.