Using jQuery to Consume ASP.NET JSON Web Services
AJAX, ASP.NET, JavaScript, UI, jQuery By Dave Ward on March 27th, 2008
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", contentType: "application/json; charset=utf-8", url: "WebService.asmx/WebMethodName", data: "{}", dataType: "json" });
As you can see, the first parameters set the request type and content-type as required by the ASP.NET AJAX framework.
When making a read-only request, the empty data parameter is the key. For reasons unknown, jQuery does not properly set the specified content-type when there is no data included.
The “{}” data parameter represents an empty JSON object, which you can think of as the JSON equivalent of null. Supplying this parameter will convince jQuery to correctly send the content-type that we’ve supplied, while it will be safely ignored by the web service.
If you’d like to see a closer examination of why this particular syntax is used, you’ll be interested in 3 mistakes to avoid when using jQuery with ASP.NET AJAX.
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> <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", data: "{}", contentType: "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.
Try it for yourself: download the source
The full example’s source code (ASP.NET 3.5 required):
Possibly related 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 or Stack Overflow instead.
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.
Other sites linking to this post
- Dew Drop - March 27 | Alvin Ashcraft's Morning Dew
- Reflective Perspective - Chris Alcock » The Morning Brew #61
- March 28th Links: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Visual Studio, Silverlight, .NET « .NET Framework tips
- Enlaces de Marzo: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Visual Studio, Silverlight, .NET « Thinking in .NET
- Wöchentliche Rundablage: WPF, Silverlight 2, ASP.NET MVC, .NET 3.5… | Code-Inside Blog
- Using jQuery to consume JSON Services « HSI Developer Blog
- Links do dia 28 de Março: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Visual Studio, Silverlight, .NET - ScottGu's Blog em Português
- Eye On .NET - Hisham Elbreky
- Using jQuery & JSON with ASP.NET at KeithRousseau.com
- Using jQuery to Consume ASP.NET « vincenthome’s Software Development
- 3 mistakes to avoid when using jQuery with ASP.NET AJAX
- jQuery with ASP.NET Json Web Services : { null != Steve }
- Mi primer plugin de jQuery = jQuery.dotNet « Walter Poch
- Good links: ASP .NET and JQuery - Programmatically Speaking ...
- My Portal Project » Blog Archive » ASP.NET Web Services from Javascript with jQuery (without the ScriptManager)
- Elegant Code » Calling Remote ASP.NET Web Services from JQuery
- Submitting an AJAX Form with ASP.NET MVC + jQuery « {Programming} & Life
- JavaScript Arrays via JQuery Ajax to an Asp.Net WebMethod | Elegant Code
- Integrating SmartGWT with ASP.NET JSON web service « Reminiscential: of or pertaining to remembrance
- JQuery Resources
- jQuery and ASP .NET MVC: browser issues | peterskim
- Amr ElGarhy » How I handle JSON dates returned by ASP.NET AJAX

Your comments
We had been thinking about doing this with some of the stuff at my work. We love jQuery, but at the same time we wanted to call out to .net web services or web methods. Have you tried to do this same setup with [WebMethod] and [ScriptMethod(ResponseFormat = ResponseFormat.Json)]? I’ve never looked at it, but I would imagine that these methods could be call in a similar fashion to web services.
I probably wasn’t clear in my last comment, I am talking about page methods in the code behind.
I haven’t tried it, but I think the request is similar and it would be doable. You would just point the request at Page.aspx/PageMethodName.
Thank you for that, it was pretty clear and your notes in the middle as well as comparison with ASP.NET AJAX style were very clear and useful
Great post! I’d be very interested to see about that page method + jQuery piece you and Justin are talking about.
Re: Page Methods. I tested it out, and you can definitely call them the exact same way.
I removed the ScriptManager and UpdatePanel from my Why UpdatePanels are Dangerous post, added jQuery, and used this code to call the page method:
It worked, just like the example above, replacing the JavaScript proxy generated by setting EnablePageMethods to true on the (now removed) ScriptManager.
Good idea, Justin. I hadn’t even thought to try that, myself.
Sweet. Glad that worked. It will certainly come in handy in the future.
How are the webmethods serialized into JSON? I notice you use msg.d. If you switch the datatype in the jquery called to text it reveals the json string {”d”:”…”} for the msg. Where is “d” specified?
The “d” is a function of how ASP.NET AJAX returns JSON serialized data. The “d” acts as a container object.
Hi.
What if I want to pass complex data(js object) into jQuery ajax call?
I haven’t had a chance to try that yet.
The way I’d suggest going about figuring it out would be watch the request in FireBug or Fiddler, using ASP.NET AJAX on the client. You’ll see what gets POSTed, then can replicate that in the jQuery call’s “data” parameter.
Great find Dave. I guess JQuery is more useful than I imagined.
hi Justin,
very good article indeed.
1 Question – would this approach work for image/binary data retrieval from REST style webservices ? I Mean can we set the dataType as binary or JPEG ?
Typically, for serving binary data like that, I’d suggest looking into an ASHX handler on the server side.
On the client side, you could asynchronously request new data through that handler by updating the src of an img tag (or whatever element you’re displaying the binary data in).
Dave, you are not alone. I also removed ScriptManager and UpdatePanel and used jQuery instead. Works like a charm. In production environment. The difference is that I retrieve data from HttpHandler.
2Anatoly: You can send any object which can be serialized to JSON (i.e. name-value pair combinations). After calling eval() on client side you work with result like it’s an object:
var data = eval(’(’ + result + ‘)’);
var msg = data.Result.Message;
As for binary, I ran into the following problem: it’s pretty normal that binary data goes with another content-type. Unfortunately, jQuery offers access to XHR (XMLHttpRequest object) and its getResponseHeader method in ‘complete’ event when ’success’ with data processing has already passed. Does anybody know the work around?
Thanks Igor
Dave, this looks good. One thing you probably would want to mention though is how to send JSON *to* the server as a parameters as well. jQuery doesn’t do JSON natively and MS Ajax requires some special ‘wrapped’ formatting.
You can do this by wrapping parameters into MS Ajax’s JSON format (outer class with parameters as properties) and using a JSON library like Crockford’s JSON2 library. In many cases this parameter passing gives more of a service feel to the application and would allow you to pass ‘complex’ types around with parameters directly received by the service or page methods.
Same approach also works with the new WCF REST services.
Hi Guys
I am trying an example similar to the one above but I am getting an invalid JSON primitive error. I have a local web service working fine and I’m attempting to retrieve a string from it. My code is not reaching the debug in the web service because it fails in the javascript beforehand with the error below.
{”Message”:”Invalid JSON primitive: origin.”,”StackTrace”:” at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize
(String input, Int32 depthLimit, JavaScriptSerializer serializer)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit
)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)\r\n at
System.Web.Script.Services.RestHandler.GetRawParamsFromPostRequest(HttpContext context, JavaScriptSerializer
serializer)\r\n at System.Web.Script.Services.RestHandler.GetRawParams(WebServiceMethodData methodData, HttpContext context)\r\n at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext
context, WebServiceMethodData methodData)”,”ExceptionType”:”System.ArgumentException”}
===============================================================
here is my ajax code…
===============================================================
$.ajax({
type: “POST”,
data: “origin=” + $(”#origin”).val() + “&destination=” + $(”#destination”).val() + “depDate=” + $(”#depDate”).val() + “&retDate=” + $(”#retDate”).val(),
url: “/WebServices/KayakService.asmx/GetFlightSearchId”,
beforeSend: function(xhr) {
xhr.setRequestHeader(”Content-type”,
“application/json; charset=utf-8″);
},
dataType: “json”,
success: function(msg) {
searchId = msg;
alert(’Search ID = ‘ + searchId)
}
});
Has anyone ran into anything like this before?
I believe the problem is that your “data” isn’t proper JSON. As Rick mentioned above, you can use the JSON2 library to help automate that process.
Take a look at this page for more info: http://www.json.org/js.html
The library is linked at the bottom of that page.
In your particular example, try changing your data parameter to:
Hi Dave
Still getting the same error after making the suggested change, will try that json2 library out tho cheers.
Mart
Sussed it Dave – I just needed to escape everythin like this…
data: ‘{”origin”:”‘ + $(”#origin”).val() + ‘”,”destination”:”‘ + $(”#destination”).val() + ‘”,”depDate”:”‘ + $(”#depDate”).val() + ‘”,”retDate”:”‘ + $(”#retDate”).val() + ‘”,”sessionId”:”‘+ sessionId +’”}’,
Just realised, this only works in Firefox, it fails in IE7 every time. I can’t seem to find out the error either, IE7 must not like the JSON format perhaps?
The JSON formatting should be the same between browsers. Are you getting a JavaScript error from IE?
Hi Dave
I’m not getting a javascript error, the ajax call just fails with no message.
I narrowed the code down and produced a simplified version and I think that it is definitely the ‘data:’ line that causes the issue.
try your example again but add in a data: block to pass a simple param. It works in both IE7 and Firefox without the ‘data:’ line but as soon as you put it in, it only works on FireFox.
I simplified mine to accept 1 param which I put as
data: ‘{”name”,”dave”}’,
this was enough to make it only work on firefox.
Cheers
Mart
Hi Dave
Did you manage to suss this one out for me? It’s a proper showstopper at the minute.
Mart
Martin, I’ve been able to reproduce the problem here, and think I’ve cured it. What I believe I found to be the problem is a bit bizarre though, so I want to make sure I’m correct.
Could you email me the modified version that you’re using, which reproduces the issue?
Hi Dave
I’ve sent you a zipped sample project with everything narrowed right down.
Thanks a lot
Mart
It turns out that IE7’s XmlHttpRequest implements setRequestHeader as an appending function instead of a replacement.
Because jQuery does set the content-type on POST requests that have data, the content-type gets set to the default “application/x-www-form-urlencoded” initially. Then in IE7, setRequestHeader was adding “application/json; charset=utf-8″ to that instead of truly setting it. So, the content-type was incorrect for JSON serialization and the web service was returning XML instead of JSON.
Bottom line, replace this:
With this:
Just keep in mind that you can only do this on calls that have POST data. If you’re making a read-only call, like in my example, you must still use the beforeSend method to set the content-type.
Dave! you’re an absolute star mate – nice one!
Mart :D
hey dave, just one detail that i didn’t realize before i started to mimic this was that the variable name on the web service and the json object key, have to be the same. i kept getting an error before i did this.
I’m having a trouble serializing a date.
Microsoft ASP.NET AJAX serialize DateTime objects using UTC format.
This is the format: \/Date(UTC TIME)\/.
For example \/Date(1208644401687)\/.
I’m trying to serialize a date using json2.js from http://www.json.org before passing it to the $.ajax call. This is the code:
var dat=”\\/Date(1208644401687)\\/”;
var myData={title:”hello”,data:dat};
var myDataSerialized = JSON.stringify(myData);
dat has a value of \/Date(1208644401687)\/ but when serialized it becomes \\/Date(1208644401687)\\/. I don’t understand why json serializer adds 2 backslash. It seems there’s no way to serialize a date in the correct format. Any suggestion?
I’m having the same problem, however this problem only exists in .net 2.0 because 3.5 seems to accept the “2008-06-26T10:20:06Z” format which means you can just use the JSON.stringify on new Date() and it will work fine, however not in 2.0.
I’m trying to figure it out. Hopefully i will get somewhere.
Hey, Dave, greeeeat post! Also Rick has some good points and great article on his site. Keep up good work guys, it really help me.
Dave and crew… I wanna ask your opinion on some stuff. My imagination has ran wild since the birth of jQuery and ajax. At the moment I want to recode all my asp.net postback work into an ajax / jquery style framework.
The reason i wanna do this is to increase the WOW factor of websites. No longer do people need to wait for that predictable flicker while they are presented with the data they want.
With lazy load of API javascript code and the like we have a platform to do what the hell we want to??? or am i much mistaken? – The possibilities in my head are endless at the minute. Enough to make me no longer need the code behind model of ASP.NET or even the AJAX part of ASP.NET for that matter (overbloat???).
Someone please bring me back down to earth before i get carried away….
Marv
I believe websites will completely change their underlying technology over the next few years, in an attempt to overcome the standard boundaries of web dev and this will spill into what everyone knows today as TV……..
Mark my words.
The Dannster (write this down)…..
I say: Get carried away!
The one thing I would suggest is waiting on the ASP.NET MVC framework to be fully released. If you’re going to start rewriting pages anyway, rewriting them MVC is going to be the way to go.
Once you get your head wrapped around the MVC methodology, it’s a thing of beauty. There’s no going back. MVC meshes very well with the idea of using RESTful web service calls to provide a rich client-side interface to your app.
Hi, I’m getting the same error message Martin was reporting. What was the final resolution? Parameterless methods work, I only hit a wall with parameters. Any help would be much appreciated.
I believe jQuery requires a string argument for “data”. Try this instead:
It’s the web service itself that will take the JSON string and parse it out, on the server side.
Cracked it. Data needed to be passed as a string.
Great post, thanks. Rich
hi there,
i have been postponing my Jquery Json learning for too long.
but i am tackling it now, no more excuses.
I also have to mention, i still working on the net 2.0
could you give us some pointers on how to get this one to work in 2.
i understand the whole, although been reluctnt to swap to ajax development for too long and after review your webconfig i get a bit lost.
any pointers on where to get the concrete info for me to know how to enable json with asp.net 2.0 in my webconfig.
thanks,
Dave
This documentation will help you get your web.config set up for using ASP.NET AJAX with 2.0:
http://www.asp.net/ajax/documentation/live/ConfiguringASPNETAJAX.aspx
I’m trying to get this to work while passing in HTML code as a string. The reason is the following: I’m attempting to store a block of html code in a database that can be modified by the user throughout the site without doing a full page postback. using javascript seemed to be the best solution, however, it fails with an invalid formatted string.
This is the data: val
Any ideas on how i would successfully pass this param through?
The double quotes in your HTML string are breaking the JSON literal. Look into HTML encoding in JavaScript, and you’ll find some techniques to handle that.
FIXED! Thanks so much!
When calling asp.net webservices with jQuery, would you need to do something special to be able to access Session data or user specific data, like membership, account properties etc.?
In order to access the session from a webservice, you need to amend the WebMethod take like so:
using jQuery resolves some problems and eases the process somehow
Thanks for the article Dave.
As discussed above ASP.NET 3.5 packages the JSON payload in a “d” object. JSON string {”d”:”…”}
Does this mean that Javascript callbacks can’t be used with ASP.NET 3.5? My understanding that cross domain information exchange depends on running eval on the returned payload.
Any information would be appreciated.
That’s correct.
The msg.d form is to prevent XSS attacks, by preventing malicious user submitted data from being arbitrarily executed via eval.
If you want to implement a JSONP capable service, you’ll need to roll your own serializer. JavaScriptObjectSerializer makes this relatively easy though, once you get into it.
I do wonder if JSONP will be with us for the long-term or not. If big name services like Flickr didn’t adopt it early, it probably would’ve been treated as a security issue and fixed in most browsers by now.
#1 – great writeup, fantastic to get a clear/concise and simple example of how to invoke simple ASP.NET exposed WebMethod’s through jQuery.
This ASP.NET DateTime JSON serialization issue I think I have a solution for. I outlined the solution as well as a regurgitated version of this original post at: http://www.overset.com/2008/07/18/simple-jquery-json-aspnet-webservice-datetime-support/
The solution is to pre-parse the DateTime JSON string response from the WebMethod/WebService before jQuery essentially eval()s it:
$.ajax({
// …
dataFilter: function (data, type) {
return data.replace(/”\\\/(Date\([0-9-]+\))\\\/”/gi, ‘$1′);
}
});
Thanks again – this has writeup is fantastic!
Fine stuff. I downloaded the source code and noticed that the RSSReader.asmx is in the Root, but RSSReader.asmx.cs is in /app_code. Is this standard practice to split web service files?
Thanks again!
It’s how Visual Studio splits the files by default, when using a website project. When using a web application project, it will keep them together.
Personally, I prefer the latter. However, since VWD Express doesn’t yet support web application projects, I use the former for code samples.
Thank you for sharing so great stuff here.
But I met a problem when trying to set up your demo.
{”Message”:”Invalid JSON primitive: origin.”,”StackTrace”:” at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize
(String input, Int32 depthLimit, JavaScriptSerializer serializer)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit
)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)\r\n at
System.Web.Script.Services.RestHandler.GetRawParamsFromPostRequest(HttpContext context, JavaScriptSerializer
serializer)\r\n at System.Web.Script.Services.RestHandler.GetRawParams(WebServiceMethodData methodData, HttpContext context)\r\n at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext
context, WebServiceMethodData methodData)”,”ExceptionType”:”System.ArgumentException”}
That indicates a problem with your “origin” data parameter in the $.ajax() call. Double check that it’s properly quoted, like:
hi Dave, great post, really useful. I am having a small issue though, I am using jQuery to call a webservice and then creating a .ascx class to create the preformatted data. The only difference is I am sending a simple ID paramater, I’ve had no problem with passing through jQuery but how would I send the parameter from the web handler to the .ascx class?
In my web handler i have tryed
Page page = new Page();
UserControl ctl = (UserControl)page.LoadControl(”PlayersReaderControl.ascx?uniqueID=”+int.parse(uniqueID));
but with no luck, please help! Thanks.
ive figured it out, was really simple. just had to set an attribute variable for the user control then retrieve it.
Very cool. This was very very helpful to me! Thanks!
Hi Dave,
Just a quick question. In your opinion, is it advisable or secure to pass a JSON string to an ASP.Net web service? For example, I have a registration form where there are fields like user name and password. Or, another example would be a login form.
Thanks!
Since a password is involved, I would only do that if the service call was SSL. That stipulated, sure. It wouldn’t be inherently any more or less secure than a postback.
Thanks and great post by the way.
I’d just like to say that this article has had the most commendable group of contibutors I have ever seen in a technical discussion and you should all be thoroughly congratulated and used a gold standard for all other discussion groups.
Thanks to all of you for a great experience, and of course thankyou Dave for the article – i’m loving the speed.
Thanks a lot for this article. Its really amazing! I downloaded the sample and its working perfectly. But when i tried using the same concept, I was getting ajax error as some people above posted. I am using RssToolKit for reading rss feeds. When I try to debug the code, the ajax error comes first. The string builder in webservice.vb shows the rss feeds but it does not return to aspx. Can anyone tell me what I should do to rectify the issue?
Specifically, what JavaScript error are you getting?
Hi, guy. do you think there is any limitation in this solution, for example, the SEO is not great due to that your content is dynamic built. any advices?
You should not defer loading of any content you want to rank for. Any kind of deferred loading is going to remove that content from what the search bots see (at least for now).
The idea here is to defer loading of ancillary content, so that the core content – what you really want to rank for and what the user cares most about – can load faster.
The original post talks more about the whys instead of the hows, as this one is more about jQuery.
thanks a lot, I got it. This technique is very powerful for the content which are not rank for. :)
Just as an FYI, I got this approach to work on a non-AJAX enabled ASP.NET site.
can u help?
I downloaded the cide and opened it
I get error
Error 1 Could not create type ‘RSSReader’. UCDelayLoad\RSSReader.asmx 1
I have framework 3.5
thanks
Hey Dave,
First off great article! I have setup a test app that is working perfectly but only if the function is called one at a time. If, however, multiple calls hit the js function the $.ajax call defaults to the error function. Is there a way that the js function running the $.ajax call can be called by many different pages at the same time? One of our sites is HTML but also is a store front, I would like to use this method display customer cart info on the HTML pages e.g. Cart(2) $54.12.
Please let me know if you have any insight on this. I am using .NET 3.5 WS2003 and calling the data from a web service.
You can definitely make multiple, concurrent calls to the service.
I’d suggest finding out what specific 500 error is returning from the server (this is what causes $.ajax to enter the “error” handler), and using that to narrow down what server side code is throwing the error.
Hello Dave, I fixed the error above… it had to do with the API I was getting the cart data from.
But a new problem with FF. I am using jquery 1.2.6 and am getting this error in FF3:
Error: [Exception... "Access to restricted URI denied" code: "1012" nsresult: "0x805303f4 (NS_ERROR_DOM_BAD_URI)" location: "/js/jquery-1.2.6.min.js Line: 28"]
Source File: file js/jquery-1.2.6.min.js
Line: 28
This works fine in IE7, any ideas?
OK, so I know this error has to do with cross domain calls. Does this mean it will not work with sub-domains either?
That’s right. XmlHttpRequest doesn’t make cross domain calls by default (for very important security reasons). I’m surprised it worked in IE either.
If you have no choice but to work with a service on another domain, you’ll need to create a proxy service on the domain where your page resides to act as a go-between.
hmmm… for some reason I thought it worked on a sub domain eg ws.domain.com when the page is at http://www.domain.com/page.html. Thanks for the info, very informative website!
Hello Dave, I have been googling all weekend looking for a good article on setting up a proxy so I can get this to work without loosing out on security. Do you know of any? Maybe be a good article for you to cover as I have found any people with the same question but no answer. (cross-domain webservice calls with jquery & asp.net)
Hi Paul,
If I understand the question properly, you want to know how to create a proxy for a web service on a different domain.You can do this a couple of ways but adding the service as a web service in your ASP.NET project is the easiest.
For ASP.NET 2.0
Right click project name and click ‘Add Web Reference’. Type in the URL of the web service and a namespace name.
For ASP.NET 3.5 sp1
Right click project name and click ‘Add Service Reference’, then click ‘Add Web Service’ (I think) at the bottom of the dialog. Then follow the 2.0 instructions as if you had just clicked ‘Add Web Reference’.
Now you are free to create your own web methods to act as wrappers for the newly created namespace.
Rich
If you want to call the .NET service with an HTTP GET, you can use the “beforeSend” method of jQuery’s ajax object to modify the properties of the XMLHTTPRequest object directly:
$.ajax({
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader(”Content-Type”, “application/json”); },
type: “GET”,
url: “/services/MyService.ashx”,
dataType: “json”,
success: function(msg){ $(”#myDiv”).text( “Data Received: ” + msg ); }
});
You really shouldn’t have to set a Content-Type header if you are using GET, but I guess we have to play by ASP.NET rules…
This post actually used the beforeSend form originally, but it turns out not to be reliable in every situation.
Hi Dave
Great article (one of many I’ve found useful on here), my question is I have a WebService method that loads a usercontrol and spits out the generated html so I can dynamically add these into the page. However what I would like to do is passing some querystring variables through when I’m loading the user control. do you know how or even if this is possible using jquery?
Cheers
Hi,
If you are talking about passing variables from the server to the client at page load, you can do a couple of things.
1. In PageLoad (or similar) add a dynamically created script block with all of your variables declared.
Page.ClientScript.RegisterClientScriptBlock(typeof(UserControl), “UserControlName”, “var variable = ” + 1 + “;”, true);
2. Take a look at jQuery’s Metadata plugin. Using this plugin you can put the variables right in the generated HTML. The plugin can be found here.
Rich
Sorry my post may have been a bit confusing.
I want the querystring variables posted to the page load method of the user control. So when the user control is loaded I can populate controls within it before it’s then passed back to the browser as pure html.
Hope that make sense ;-)
You can access the querystring from Page.Request.QueryString within the user control.
Rich
here is my jquery method
function WSClicked() {
$.ajax({
type: “POST”,
contentType: “application/json; charset=utf-8″,
data: “{path:’controls/TestControl.ascx’}”,
dataType: “json”,
url: ‘Services/Ajax.asmx/RenderUC’,
error: function(XMLHttpRequest, text, error) {
$(”#WSResult”).text(XMLHttpRequest.responseText);
},
success: function(msg) {
$(”#WSResult”).html(msg.d);
}
});
}
I’m trying to achieve the same as this article (http://samuelmueller.com/post/2008/12/20/Dynamically-Loading-ASPNET-User-Controls-with-jQuery.aspx) except using a web service. I’m just not sure on how to pass variables from jquery so that they are accessible in the Request.Querystring of the Page_Load of the user control.
Can’t you just chuck the query string on the end of that usercontrol url?
This is an example of using a web service (and you can also do this in a page method the same way) to instantiate a user control and render it as HTML:
http://encosia.com/2008/02/05/boost-aspnet-performance-with-deferred-content-loading/
To pass a parameter to your user control, add a public property to the user control’s class (in the code-behind), pass that data to your page method or web service, and then set that property before rendering the control.
Can’t you just chuck the query string on the end of that usercontrol url?
no it dies when Page.Load(”path of control”) is called as it can’t find the address because of the “?action=load” on the end
Hey Dave,
Is it possible to pass a generil List as parameter to the Method?
so that i got a method in the webservice like
public bool Something(List){
…
return true;
}
thanks
dave
I have managed to pass a .NET class to a ASMX ScriptMehod but not to a WCF Endpoint. I’d be interested if it is possibe or not.
If you add the AspNetCompatibilityRequirements attribute to your WCF service classes, you can get the same serialize/deserialize functionality that ASMX “ScriptServices” provide.
Sorry, I cracked it.
I was trying to pass a .NET class to a WCF Endpoint using the GET Verb, but couldn’t get it work. Once you replied I took another look at firebug and realised that I wasn’t encoding the # in the __type property.
Once encoded to %23, the code worked fine.
Yes. The JavaScript counterpart of a List (or any collection) is an array. For example (assuming my syntax is correct), you could pass:
As the data parameter to call a function declared as:
Generally speaking, I’d suggest using an array as the parameter type on the .NET side. It’s less overhead and it’s a bit more clear later.
hi all
if u all are experiencing the same problem as me my flash cant get data from json on ie7.
just escape ur parameter.
e.g param:escape($.toJSON(data))
thanks sherrymerry
great article
Hi Dave,
By calling web services via. jquery, we are specifying url of the webservice right in the source. So, will it not be easy for others to just look at it and add a reference to the web service and make fake calls to the webservice.
Actually I am implementing this type of call when user isn’t authenticated, so no ticket is passed over the network to check the validity of the request.
Could you tell us what would be the basic security measures we can incorporate in the appln.
Thanks,
Sundeep.
ASMX services are very similar to ASPX pages in terms of security issues. You can secure them the same way (e.g. forms authentication, session state, etc).
Thanks for the reply.
As I mentioned earlier, in that particular aspx page user is not authenticated via forms authentication.
I would like to expand on this, please correct me if I am wrong.
Say I had written the code: Response.Write(”Hello”);
in the code behind of aspx page. I needn’t check whether user is authenticated or not.
Same thing when I expose through a webservice like In webmethod: return “hello”;
Anyone can add reference to this webservice and call this method.
Its just an example to put my concern. I don’t want anyone (un-authenticated users) to use the web services.
… very informative
Hi Everybody,
under ASP 3.5 my web service call from jquery ajax succeeds WITH and WITHOUT parameters, no prob at all.
Unfortunately my client runs asp.net 2.0 and I run into following probs:
- contentType: “application/json; charset=utf-8″,
is never accepted by my web service (.net 2.0) and I get following error:
System.InvalidOperationException: Request format is invalid: application/json; charset=utf-8.
at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
- I can change the contentType to: text/xml or application/x-www-form-urlencoded and the web service succeeds AS LONG AS I DO NOT pass in any paramter data meaning my web method cannot have any parameters (like: MyWebMethod(int Count){…}
Once I start and add a parameter to my web method my web service returns the message that the parameter is missing from the ajax call even if I filled in the data: field in the jquery ajax call.
That makes sense because I did not specify that my contenttype is json.
Any ideas why I run into these probs with ASP.NET 2.0? I have installed the AJAX web extensions 1.0, so that can’t be an issue.
Thanks
Franco
Have you installed ASP.NET AJAX 1.0 on the server running 2.0, and updated the site’s web.config accordingly?
Also, keep in mind that once you get it working under 2.0, the .d in the return value won’t be present.
$.ajax({
type: “POST”,
url: “WebService.asmx/SendName”,
data: “{’firstName’:'Chris’,'lastName’:'Brandsma’}”,
contentType: “application/json; charset=utf-8″,
dataType: “json”,
success: function(msg) {
}
});
[WebMethod]
public static string GetDate(string firstName, string lastName)
{
return string.Format(”{0},{1},{2}”, firstName, lastName, DateTime.Now);
}
Using this when using parameters
Dave,
I notce that your examples always access the returned json as msg.d.Property. However, this doesn’t work for me. I have to eval it fot it to work: $.ajax({
type: “POST”,
contentType: “application/json; charset=utf-8″,
url: “Client/ws.asmx/GetDetails”,
data: “{’dId’:'” + id + “‘}”,
dataType: “json”,
success: function(result)
{
var parsed = eval(”(” + result.d + “)”);
$(”#” + elementId).html(parsed.Details);
}
});
Otherwise I get the dreaded undefined. Is that right?
It sounds like you’re manually serializing and returning a JSON string in your web method. Is that the case?
No, I have a helper class that uses the framework methods. I use both of these:
public static string ToJson(this object obj)
{
JavaScriptSerializer js = new JavaScriptSerializer();
string s = js.Serialize(obj);
return s;
}
public static string ToJson(this object obj, Type type)
{
string jsonString = string.Empty;
DataContractJsonSerializer serializer = new DataContractJsonSerializer(type);
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
jsonString = Encoding.Default.GetString(ms.ToArray());
}
return jsonString;
}
My WebService method does this: return myobj.ToJson();
I’ve favored the javascript version because it handles List a lot easier.
What’s happening is you’re serializing the object and returning a string, but that returned string is also being serialized as JSON. The framework automatically handles that for “ScriptServices”.
If you return your object directly (return myobj instead of return myobj.ToJson()), ASP.NET AJAX will automatically JSON serialize it for you and you won’t need the extra eval().
That was it! Thanks. It’s funny, I had never seen/noticed that details before.
I just can’t seem to get this jquery/flexigrid thing working. :-(
I have a wcf rest svc that returns a list of x, example JSON:
{”CategoryList”:[{"Carrier":null,"Category":"Sample Kit","Dscr":"AID Sample Kit","FormCode":"AIDSampKit","MktgAppCode":"Sales","OccasionCode":"Prospect","ProductionPrice":0,"SubCatgory":"9x12","Uri":null,"psLength":0}]}
I access that list via a call to a websvc:
http://192.168.1.8/C2M/SlsOrderSvc.svc/json/clients/AIDmv0xl2h50/catalog/list
which returns a nice JSON formatted list of values, each and every time.
I just can’t get FlexiGrid to display them.
Is there some documentation that tells me if FlexiGrid needs to have the data formatted a certain way? Or contain certain fields/values?
Do i have to use a table to get FlexiGrid to be able to display the data and do I have to feed it row by row?
I would think that I could just point FlexiGrid at a datasource (web svc call that returns JSON formatted data) and it would be happy.
I have seen many examples of how to do this for C#/VB.Net/ASP.Net and JavaScript, but I can not seem to make it work.
I can nicely use JavaScript, Ajax and a Template and iterate the JSON response and get a nicely (simple) formatted table on the web page…
But I’d rather have FlexiGrid.
So where is this FlexiGrid manual that I have not been able to find?
Thanx,
G
I haven’t used FlexiGrid, so I’m not familiar with its quirks.
For a better supported/documented jQuery grid, you might want to try jqGrid or DataTables.
Dave,
Thanx, checking it out now.
G
Hi Dave,
Just one quick question. I have an application set up that needs to read data from a webservice located on another domain (www.webservicex.net), but it only returns XML and not JSON. Im aware of the XSS issues, and I also found out that an ‘xml’ dataType won’t work in FireFox, but will in IE. What would your suggestion be in this case? The application is intended (as always) to be 100% accessible and needs to work cross-browser. If needed, I can send you the code that I currently have. Ever since I started using jQuery I’ve been hooked. If I can learn properly how to replace all my UpdatePanel functionality using jQuery alone, it will benefit me greatly! TIA!
I have one BIG problem. Even though my sample code works just great on the same machine calling a dotnet ASMX file, as soon as I call the URL from a different machine, nothing works and I get an error saying my URL ended in some wrong way. To be exact, this is the error message – “Request format is unrecognized for URL unexpectedly ending in ‘/HelloWorld’.” But I don’t get this error message if I am on the same machine where the web service and the html file with jQuery is located.
This is what my code looks like on JS –
—————————————
$.ajax({
url: “/myapp/Service.asmx/HelloWorld”,
contentType: “application/x-www-form-urlencoded”,
type: “POST”,
data: “name=Khan”,
success: function(msg)
{
document.getElementById(”result”).innerText = msg;
},
error: function(req, status, err)
{
document.getElementById(”result”).innerText = req.responseText;
}
});
———————————-
Everything here works just fine when I call the URL (url of the html file where jQuery is located) from the same machine where my webservice is. Then I go to a different machine and call the same exact URL, and nothing works.
Can someone please help? What am I missing? I tried the same thing with Prototype.js – again, everything works except when I go to a different machine.
Thanks very much.
Khan
I’m not sure how your machines are configured, but the URL to the service on a production machine is probably going to be /Service.asmx/HelloWorld, instead of /myapp/Service.asmx/HelloWorld.
Turns out everything was going in the right place – except that Web.Config file of my web service needed to be updated to be accessed from remote machine. Here is the solution in case if anyone else had the similar issue -
Disable the HttpGet, but keep the post. In that case, everything works great. This is a solution for the Dot Net 2.0 – I am not sure about the other versions of Dot Net though. Apparently by default Dot Net 2.0 disables the “HttpPost” and has to be added. This is why everything was working from the same machine where the web service and the javascript app was located, but would not work if i call the javascript app from a different machine.
Hope it helps others, who didn’t know like me :)
Khan
Hi Dave, sorry to worry u…I imagine u must be busy, but if possible, could u please assist me with the issue I am experiencing (my comment is just above Khan’s). Much appreciated!
Email me your code. I’m not sure I understand the problem you’re having.
Thanx Dave! I’ve just emailed you
I tried about code with VS2008, it didn’t work for me.
I even tried with complete URL of web the service still no luck.
In the debug mode, it didn’t come to web service code at all.
Can you help me to resolve my issue? I am not sure whats wrong I am doing here?
Thanks,
Raj
That’s too vague for me to give you much specific advice. A couple things I’d suggest are:
Double check that you don’t have any JavaScript errors on your page. One JavaScript error will abort execution of JavaScript on the rest of your page (like a single compilation error will in your code-behind).
Try running it in Firefox with the Firebug console open. This way, you can see if the service call is made at all and/or if the server is returning a 500 error.