Rick Strahl's Web Log

Since I've posted a few jQuery posts recently I've gotten a bunch of feedback to have more content on using jQuery in Ajax scenarios and showing some examples on how to use jQuery to cut out ASP.NET Ajax. In this post I'll show how you can use jQuery to call a WCF REST service without requiring the ASP.NET AJAX ScriptManager and the client scripts that it loads by default. Note although I haven't tried it recently the same approach should also work with ASMX style services.

WCF 3.5 includes REST functionality and one of the features of the new WCF webHttp binding is to return results in a variety of ways that are URL accessible. WCF has always supported plain URL HTTP access, but it's not been real formal and had somewhat limited functionality as parameters had to be encodable as query string parameters. With the webHttp binding there's now an official WCF protocol geared towards providing ASP.NET AJAX JSON compatibility (using WebScript behavior) as well of a slightly cleaner raw JSON implementation (basic webHttp binding).

You can return XML (default), JSON or raw data from WCF REST services. Regardless of content type, natively WCF always wants to return content in a 'wrapped' format which means that both inbound parameters and outbound results are wrapped into an object.

Let's take a look at the message format for a REST JSON service method.

[ServiceContract(Name="StockService",Namespace="JsonStockService")]

publicinterfaceIJsonStockService

{

[OperationContract]

[WebInvoke(Method="POST",

BodyStyle=WebMessageBodyStyle.Wrapped,

ResponseFormat=WebMessageFormat.Json

)]

StockQuote GetStockQuote(string symbol);

..

The input message on the wire looks like this:

{"symbol":"MSFT"}

The response looks like this:

{"GetStockQuoteResult":

{"Company":"MICROSOFT CP",

"LastPrice":30.00,

"LastQuoteTime":

"\/Date(1208559600000-0700)\/",

"LastQuoteTimeString":"Apr 18, 4:00PM",

"NetChange":0.78,

"OpenPrice":29.99,

"Symbol":"MSFT"}

}

Notice that in both cases an object is used. For the inbound data all parameters are wrapped into an object and rather than just passing the value, the name of the parameter becomes a property in the JSON object map that gets sent to the server. This is actually quite useful - if you're just sending a raw JSON structure you could only pass a single parameter to the server - and that option is also available via the Web BodyStyle=WebMessageBodyStyle.Bare option on the service method.

The outbound result set is also wrapped into an object which is a lot less useful. This is a hold over from WCF which wraps all responses into a message result object, which usually makes sense in order to support multiple result values (ie. out parameters etc.). In a Web scenario however this doesn't really buy you much. Nevertheless if you want to pass multiple parameters to the server you have to use this wrapped format along with the result value.

Calling with jQuery

If you're using jQuery and you'd like to call a WCF REST service it's actually quite easy either with bare or wrapped messages. Bare messages are easier to work with since they skip the wrapping shown above, but as I mentioned you're limited to a single input parameter. So if your service has any complexity you'll likely want to use wrapped messages.

You can opt to either call services using the ASP.NET Ajax logic (WebScriptService behavior) or using the raw service functionality which is shown above.

To call these methods with jQuery is fairly straight forward in concept - jQuery includes both low level and highlevel methods that can call a URL and return JSON data. The two methods available are $.getJSON() which automatically parses result JSON data and $.ajax(), which is a lower level function that has many options for making remote calls and returning data.

getJSON() is useful for simple scenarios where the server returns JSON, but it doesn't allow you to pass JSON data TO the server. The only way to send data to the server with getJSON is via query string or POST data that is sent as standard POST key/value pairs. In all but the simplest scenarios getJSON() is not all that useful.

The lower level $.ajax method is more flexible, but even so it still lacks the capability to pass JSON data TO the server. So little extra work and some external JSON support is required to create JSON output on the client as well as dealing with Microsoft Ajax's date formatting.

Personally I prefer to use a wrapper method for making JSON calls to the server to encapsulate this functionality. Note although this method seems somewhat lengthy it deals with a few important issues that you need to take care of when calling WCF REST Services:

// *** Service Calling Proxy Class

function serviceProxy(serviceUrl)

{

var _I = this;

this.serviceUrl = serviceUrl;

// *** Call a wrapped object

this.invoke = function(method,data,callback,error,bare)

{

// *** Convert input data into JSON - REQUIRES Json2.js

var json = JSON2.stringify(data);

// *** The service endpoint URL

var url = _I.serviceUrl + method;

$.ajax( {

url: url,

data: json,

type: "POST",

processData: false,

contentType: "application/json",

timeout: 10000,

dataType: "text", // not "json" we'll parse

success:

function(res)

{

if (!callback) return;

// *** Use json library so we can fix up MS AJAX dates

var result = JSON2.parse(res);

// *** Bare message IS result

if (bare)

{ callback(result); return; }

// *** Wrapped message contains top level object node

// *** strip it off

for(var property in result)

{

callback( result[property] );

break;

}

},

error: function(xhr) {

if (!error) return;

if (xhr.responseText)

{

var err = JSON2.parse(xhr.responseText);

if (err)

error(err);

else

error( { Message: "Unknown server error." })

}

return;

}

});

}

}

// *** Create a static instance

var Proxy = new serviceProxy("JsonStockService.svc/");

WCF services are called by their URL plus the methodname appended in the URL's extra path, so here:

JsonStockService.svc/GetStockQuote

is the URI that determines the service and method that is to be called on it.

The code above uses the core jQuery $.ajax() function which is the 'low level' mechanism for specifying various options. Above I'm telling it to accept raw string input (in JSON format), convert the response from JSON into an object by evaling the result, as well as specifying the content type and timeout. Finally a callback handler and error callback are specified.

Note that I override the success handler here to factor out the wrapped response object so that the value received in the callback handler is really only the result and not the wrapped result object. More on this in a second.

The call for the above StockQuote(symbol) call looks like this (including some app specific code that uses the result data):

var symbol = $("#txtSymbol").val();

Proxy.invoke("GetStockQuote",{ symbol: symbol },

function (result)

{

//var result = serviceResponse.GetStockQuoteResult;

$("#StockName").text( result.Company + " (" + result.Symbol + ")" ) ;

$("#LastPrice").text(result.LastPrice.toFixed(2));

$("#OpenPrice").text(result.OpenPrice.toFixed(2));

$("#QuoteTime").text(result.LastQuoteTimeString);

$("#NetChange").text(result.NetChange.toFixed(2));

// *** if hidden make visible

var sr = $("#divStockQuoteResult:hidden").slideDown("slow");

// *** Also graph it

var stocks = [];

stocks.push(result.Symbol);

var url = GetStockGraphUrl(stocks,result.Company,350,150,2);

$("#imgStockQuoteGraph").attr("src",url);

},

onPageError);

Parameters are passed in as { parm1: "value1", parm2: 120.00 } etc. - you do have to know the parameter names as parameters are matched by name not position.

The result is returned to the inline callback function in the code above and that code assigns the StockQuote data into the document. Notice that the result returned to the callback function is actually NOT a wrapped object. The top level object has been stripped off so the wrapper is not there anymore.

If you look at the the ajaxJSON function, you can see that it looks for the first result property in the actual object that WCF returns and uses IT to call the callback function instead - so it's indirect routing. This saves you from the one line of code commented out above and having to know exactly what that Result message name is ( WCF uses <methodName>Result). Not that one line of code would kill you, but it's definitely cleaner and more portable.

The same approach should also work with ASMX style services BTW which uses the same messaging format.

JSON encoding

Note that the ajaxJSON function requires JSON encoding. jQuery doesn't have any native JSON encoding functionality (which seems a big omission, but was probably done to preserve the small footprint). However there are a number of JSON implementations available. Above I'm using the JSON2.js file from Douglas Crockford to serialize the parameter object map into JSON.

There's another wrinkle though: Date formatting. Take another look at the stock quote returned from WCF:

{"GetStockQuoteResult":

{"Company":"MICROSOFT CP",

"LastPrice":30.00,

"LastQuoteTime":

"\/Date(1208559600000-0700)\/",

"LastQuoteTimeString":"Apr 18, 4:00PM",

"NetChange":0.78,

"OpenPrice":29.99,

"Symbol":"MSFT"}

}

There's no JavaScript date literal and Microsoft engineered a custom date format that is essentially a marked up string. The format is a string that's encoded and contains the standard new Date(milliseconds since 1970) value. But the actual type of the date value in JSON is a string. If you use standard JSON converters the value will be returned as a string exactly as you see it above. I've talked about the date issues, and hacking existing JSON implementations before. I've modified Crockford's JSON2.JS to support the Microsoft date format so it properly encodes in and outbound data. You can download the hacked JSON2_MsDates.zip if you're interested. You can look at the code to see the modifications that were required, which essentially amounts to pre filtering parsed data before evaling on the .toJSON end and dropping the Data format that Date.prototype.toJSON() produces and instead creating a string in the required format above when doing object encoding.

Bare Messages

If you want a cleaner message format and you're content with single parameter inputs to functions then the WebMessageBodyStyle.Bare can work for you. Bare gives you a single JSON parameter you can pass that is automatically mapped to the first and only parameter of a method. You can't use Bare with any service methods (other than GET input) that include more than one parameter - the service will throw an exception when you access any method (beware: it's a RUNTIME error!).

Bare messages are easier to work with but they are limited because of the single parameter. You can use a single parameter on the server and make that input a complex type like an array to simulate multiple parameters. Using input objects or arrays can work for this. While this works realize that WCF requires an exact type match so any input 'wrapper' types you create yourself have to be mappable to a .NET type.

My first instinct with WCF's web bindings was always to use Bare, but ultimately the wrapped format provides more flexibility even if it is a little uglier on the wire. For AJAX services wrapped seems to make more sense.

Ideally, I would have preferred even more control - wrapped input messages and bare output messages, but I guess you can't have everything <g>...

Other Input Alternatives

Passing JSON messages is one thing you can do - the other option is to pass raw POST variables, which is something that can be done natively with jQuery without requiring a JSON encoder. Basically jQuery allows you to specify data as an object map, and it can turn the object into regular encoded POST parameters.

If you prefer the simplified logic and you can use POST input data (which works well if you rather post back to a handler or the same ASPX page) you can get away with the following:

function ajaxJsonPost(method,data,callback,error)

{

var url = "JsonStockService.svc/" + method;

$.ajax( {

url: url,

data: data,

type: "POST",

processData: true,

contentType: "application/json",

timeout: 10000,

dataType: "json",

success: callback,

error: error

});

}

When you send data like this you can actually change the message format to Bare and get just a raw object response. jQuery can either except a raw POST string for the data parameter or an object whose properties and values are turned into POST key value pairs.

If you want to use POST behavior with WCF though, you need to enable ASPNET Compatibility on the REST service - otherwise the HttpContext.Current.Request is not available since WCF REST by default is trying to be host agnostic. For more information on how to configure WCF REST services check my previous post on WCF REST configuration last week.

This format might be preferrable if you are indeed building a public API that will be externally accessed. Raw POST data interchange is more common for many Ajax libraries, and also lends it self to straight HTTP clients that don't have JSON encoding features built in. For public APIs this makes plenty of sense. Remember that if you care about date formatting you may want to add the explicit JSON2 parsing code into the success callback (I left this out here for simplicities sake).

Error Handling

One more issue you'll want to be very careful of with WCF REST Services when you're using non-WebScriptService (ASP.NET AJAX style) behavior: When an error occurs WCF unfortunately throws an HTML error page rather than a JSON or XML fault message. That's a big problem if you want to return meaningful error messages to your client application - the only way to retrieve the error is by parsing the messy and very bulky HTML document returned.I've tried finding some way to get the REST services to throw a full JSON based error message and I haven't found a way to do this. JSON error messages seem to only work when you're using WebScriptService which is the full ASP.NET AJAX emulation. Under WebScriptService behavior the message returns the standard Exception like structure that includes a .Message and .StackTrace property that lets you echo back errors more easily.

In the end this means that even if you are using a non-MS Ajax client it might be the best solution to use the ASP.NET AJAX style WebHttp binding, simply because it provides the behavior that you most commonly require. There's nothing lost by doing so. You don't incur any client ASP.NET AJAX client requirements, but you do get the wrapped format input and exceptions properly wrapped on errors, plus this format is easier to implement because it doesn't require any special attributes on each individual operation/method as it's a fixed format. On the downside you do lose the ability to use UrlTemplates which might be useful in some situations, but it's probably not a common scenario that you need this for pure AJAX services.

@Ed - depends on what you're doing with the API. Personally I'd strive for consistency in the API so if you have a number of methods that are JSON accessible and some require either multiple parameters or complex parameters (like arrays) I'd definitely go with POST for the entire API so you can use one mechanism for calling all methods regardless of parameter types. In this case this API is an application level interface that has an application calling it for AJAX calls exclusively.

For a more public API I suspect my goal would be to make as much as possible available via GET access because that's usually easier to consume for a variety of clients.

LOL.. "how to use jQuery to cut out ASP.NET Ajax" I just spent the last month weeding through the ASP.NET AJAX Framework, it's pretty embarrassing. I concluded that ASP.NET AJAX is for Dummies. :)

I started looking into alternatives to JSON serialization and this post does just that. Now I'll dig into WCF a little deeper.

Thanks!

#re: jQuery AJAX calls to a WCF REST Service by
Michael
April 22, 2008 @ 12:12pm

Just wanted to point to a possible suggestion with your JSON2 hack. It is suggested on http://www.json.org/js.html that you can use an optional 'reviver' filter function "that will be called for every key and value at every level of the final result. Each value will be replaced by the result of the filter function. This can be used to reform generic objects into instances of classes, or to transform date strings into Date objects."

Michael - yeah I saw that actually, but the problem with the JSON creation at least is that the result MS Ajax expects is a string and JSON2 will double parse. No matter what the code needs to be hacked, so the above works and is fairly lean.

I actually still use my original original JSON (V1) code that I hacked a long time ago. Never had a problem with that either and its considerably lighter.

#Passing a JSON object to a WCF service with jQuery by
Denny.NETApril 25, 2008 @ 5:29pm

Also, @Adam: can you (or anyone else) shed some light into the shortcomings of ASP.NET AJAX? I ask because I'm about to embark on a project and I'm trying to wrap my head around a REST approach and see what benefits it would offer in developing AJAX enabled applications. I truly get REST for *end users* and it's abundantly clear why having all of your resources uniquely identifiable by URL is a big win, but I'm struggling with REST for developers in AJAX application scenarios.

Also: why bother with jQuery (or any other AJAX library) to make simple data retrieval requests when ASP.NET AJAX does that bit just fine? I'm a bit puzzled by this as well. I can understand wanting to use the utilities and conveniences of a given library, but why shun the default ASP.NET AJAX requests?

@Charles - these are valid points. As I've mentioned many times before if you are already using ASP.NET AJAX then there's little point in going through the above excercise. However, I think that more and more developers are more than happy to cut out ASP.NET AJAX.

Here's why I think it matters: If you are using Web Services you will still need to apply the data returned somehow, which means writing DOM and JavaScript code. That's where ASP.NET AJAX falls completely flat providing practically zero value at the moment. So if I want to efficiently write client script code it's more than likely that I will already be using a client library of some sort.

If I do use a client library then WHY SHOULD I bother using ASP.NET AJAX when I can write that same Web Service call code with a few lines of client code? As an advantage I can cut out System.Web.Extensions and the configuration nightmare it introduces, plus 65k+ of client script libraries and I'm not losing anything in terms of functionality. That seems like a win-win situation to me.

It'd be a different story if the Microsoft client library actually had some value on the client, but for your day to day development it provides very little useful features so it's just dead weight (ie. ScriptManager on a page alone will cause the library to load). Further I don't appreciate the design of the client libraries with it's rigid framework APIs that require reams of code to simulate .NET like structure that is IMHO inappropriate for JavaScript.

This is of course my opinion, and maybe it's an extreme view by I'm pragmatic about the tools I use and create - I want things to be easy and reasonably transparent and the current ASP.NET AJAX libraries are anything but.

There are problems with all JavaScript tools, but there's always a path of least resistance and frankly ASP.NET AJAX is not it at least not for me.

As to the REST issue: Yes the example here is more RPC style, but the same approach can be used with a more REST centric interface. There are many different ways that you can call these methods and return data it just so happens that the examples above are more RPC style. But you can still use pure REST based protocol rules and STILL return RPC style messages. There's really a fine line and the semantics can overlap significantly. The difference really lies in what clients are your target audience - if you have an application specific AJAX API most likely you'll tend towards an RPC style mechanism, where a public access API may be more general with query string based input that is easier to access generically without a specific JSON client.

nice post, this helped me out a lot getting WCF working with jQuery. I think you can get the best of both worlds - wrapped requests and bare responses by using WebMessageBodyStyle.WrappedRequest. Have you tried this?

@Steve - yes, but the message style is applied to both request and response so AFAIK you can't get wrapped input and bare response. But that's fine - the above ServiceProxy object will manage wrapped results and return only a bare response from it to the caller.

I think you can - I was confused about it at first as there's only one a single BodyStyle property on the WebInvoke attribute, but there are 4 options in the enumeration:

Bare, Wrapped, WrappedRequest and WrappedResponse - if you use WrappedRequest you get a bare Response and if you use WrappedResponse you get a bare request. It makes for a pretty unintuitive API really but unless I am mistaken it gives you all the options you need. I've just got a jQuery call running against a WCF service using a bare request and wrapped response anyway so I'm fairly certain it's working :)

I'd like to preface by saying that I've long converted to an all client DOM approach to building web UIs over years ago (I haven't written an ASPX page with UI controls and post back in over three years).

You are spot on about the lack of features in the ASP.NET AJAX libraries for DOM support (or perhaps it's just not well documented?) as I have relied on Dojo and prototype to augment the client side libraries for all of my projects.

It was good to see your points articulated (particularly the config...it's a pain to merge with SharePoint configuration, for example). However, I do still believe there is some value in the ASP.NET AJAX client library in that it reduces the amount of custom code required to make the actual calls.

Be wary of investing processes which rely heavily on the \"tea leaf\" reading of stock charts or graphs. Technical analysis can be valuable but ultimately there should be a foundation of solid, clearly understood metrics.

#re: jQuery AJAX calls to a WCF REST Service by
Travis
August 27, 2008 @ 10:35pm

Nice article. What if you want to use the json enabled wcf service in another domain. I understand the implications of this, but I have yet to understand the how. Any recommendations for me? Some have said to use callbcks, which all similar to how other company's have done so for widgets. I am not sure where I should start.

Again, I have a question about something that is M$ related, and your blog satisfies. It seems that my instincts for development always seem to follow yours (albeit, a day late and a dollar short) ;-).

I completely agree w/your comments re:ASP.NET AJAX also. I was so looking forward to it's release, but when it was actually released, and I studied it, I realized what a dog it is. I sometimes think that except for a few folks, Microsoft no longer has very many good architects--too many cluster youknowwhats have come out of there in the last few years.

The combo of ASP.NET/WCF/JQuery is IMO, definitely the way to go. Thanks for the great research and examples.

#re: jQuery AJAX calls to a WCF REST Service by
Namlet
September 17, 2008 @ 10:42am

Great info! I'm having a problem with a .NET 2.0 asmx service. I am able to send hand crafted JSON data to other methods, and return and parse a JSON return correctly. But I have one method that requires a larger object, and I don't know how to get that data into this method. Every attempt fails.

I have tried both forms of JSON string:"{'fname':'Jimmy', 'lname':'Smith'}" - returned from a custom method and JSON.stringify'ed"[{'name':'fname', 'value':'Jimmy'},{'name':'lname', 'value':'Smith'}]" - this came from using serializeArray() then JSON.stringify

I've tried strings, objects, hashtables, I just don't know how to get to the data. With the other Web Methods I send a simple {'var':'value'} and reference it with myMethod(string var) and it works fine. How can I do this with this large object with 57 fields?

Its a very well written post, and brought most of the positives. I have been following your blog from sometime now and have always benefited from the same.

I have been into WCF REST Service, and am pretty convinced about the usability and effectiveness of the same. I agree that usage of "script manager" is unnecessary heavy and config madness remains. Last September i started to dig into ASP.Net MVC, and i found out jQuery getting used in the same. But i found it to be very raw... and Visual Studio still doesnt support much of it still...

Would you recommend to go with it whenever it comes clean? Am pretty much happy with using REST Services along with jQuery right now. It is performant and less complicated, but somehow i feel maintaining might be a worry. Whats your take on it?

Do you have an example for calling a WCF service that is not part of your web application but actually running alongside it under a different port in Cassini? The reason I ask is because, thus far I have been unable to get this to work.

I have created a WCF Service called Common in my web application.

I have created the same thing in another WCF Web Service project.

The files look identical with the exception of the namespaces.

This works...

var Proxy = new serviceProxy("/Common.svc/");

This does NOT work...

var Proxy = new serviceProxy("http://localhost:999/Common.svc/");

I have also compared web.config files and both make the same changes to the file, so there is nothing out of the ordinary there either.

If you are unable to reproduce this behavior I would be happy to send you an example. I look forward to your reply.

@Chris - you can't call a service directly with XHR if it's not in the same EXACT domain and port environment. A port change is like a different domain so direct calls via XHR will cause access violations as it should.

If you're calling 'external' services in this way you need to proxy on the server or use browser hacks (like iFrames or script loading) to make the requests.

Thanks for the response. I didn't expect a port change to be consider a different domain. Furthermore I didn't really expect it to block me at all even if it were.

I am going to try and rethink what I was trying to do here.

I have multiple web sites that do a lot of the same things. I was hoping to create a web service that all of them could call directly from client script rather than having to call back into themselves and then making the call through a proxy.

But if what you are saying is true, I either need to convert all my web applications to go through IIS and forget about Cassini or I need to start setting up proxies...

#re: jQuery AJAX calls to a WCF REST Service by
SynDev
February 26, 2009 @ 12:25pm

Thanks Rick. It is a great post.

One question though ... As you explained above in response to Chris's question, I am using iframe to host WPFBrowser application (produces xaml page) who is talking to local WCF service. This service is already running on the machine and thats how I want to consume it. So the xaml page is added through iframe on aspx page. I found out that the communication between xaml and aspx page is possible only via cookies or query string. I was wondering if there is any possibility to use JQuery in that senario so that objects can be passed between xaml and aspx.

thanks ...looking forward to your reply.

#re: jQuery AJAX calls to a WCF REST Service by
ms440
March 11, 2009 @ 2:46pm

@KierenH - it depends on how you're passing the data. THe way you're passing the data it will be encoded as a POST variable. You can pick that up as a string on the server then use JavaScriptSerializer or DataContractSerializer against it to turn it back into a .NET object, but it won't be automatic. For automatic conversion of types you can use WCF/ASMX services, but you need code like described in this post to properly wrap the types.

I'd recommend going the latter route. There are lots of issues you need to deal with like date conversions that are easy to miss if you do the conversion yourself.

@Amir - Because it doesn't work with .NET services for the most part - unless you have no input parameters on service method or input parameters that are only simple types the input can't be sent easily just via querystring.

These services expect input parameters as JSON input and traditionally via POST data. You also need to be able to post process the returned JSON result to handle date fixup. The why's are all covered in the post.

Hey Rick... not sure if you're notified for older posts, but I'll give this a shot.

There's one part of the equation that I'm missing in using JSON for WCF, and that's getting Silverlight to send JSON in its request to a service. So for example, you say in this post about what the input request looks like "on the wire," well how do you force the client (again, I'm using Silverlight) to format its request as JSON? My Googability is failing me!

The guy use old asmx web service. I tried relatively the same using WCF but can't get things to work. Help!

Thx!

#re: jQuery AJAX calls to a WCF REST Service by
Yauhem
August 11, 2009 @ 11:28pm

But how to deal with timezone problems with wcf? I have used your json2 fix with ms date suppport. BUt the following issue still exists:if I create date in javascript (like new Date for today) I will have UTC prefix (for example on today Thu Aug 12 9:24:00 UTC+0300 2009). And when transferring to wcf I will receivetime 6.24 (i.e. 9.24-3). All tests was local. SO even without different timezone. On current moment I am thinking about datejs library function setTimezone("GMT"). but it looks like bad hack. how you deal with this issue?

thanks for this article - just one thing that I've noticed. I've just rolled out your datetime fix for JSON2.js into a dev website. Just as I was about to update my homepage's script reference from the 'real' json2.js to the new one, I noticed that I hadn't even referenced it yet!

Even so, all my code was working...

turns out that IE8 has an instrinsic JSON object based on the code designed by Doug Crockford - and ironically that also appears to suffer from the same problem...

#re: jQuery AJAX calls to a WCF REST Service by
Andreas
November 27, 2009 @ 1:11am

Hi Rick,

And good job on this well written article.

As with Cris here, I would like to use 'external' web services.

Why? Because I sometimes tend to add features to an existing webside running on a different platform than mine. The easy way out as I can see it would be an 'external' web service I can access from jQuery.

Main issue with my situation is that I have a AJAX enabled WCF service. Running it alone on the browser with the needed input string like this ...localhost/TestWCFAjax.svc/Method1?inp1=....I do get results without any issue. Problem arises, when I include the javascript proxy (created by way of ...localhost/TestWCFAjax.svc/jsDebug - and say I named the javascript file as TestWCFAjax.js). I do create a var ServiceProxy = WCFAEService.WCFSearchAE._staticInstance;

Then when I try to test from my test page in my ASP.Net web application, in the onclick javascript handler of a button, the WCF proxy method call seems to be fine, the execution goes through the invoke call and then in the onComplete method, I get a statusCode = 12030 and the corresponding message being Method Not Found. And the failedCallback method gets called and I alert the message accordingly. I did follow the config setting up for AJAX enabled WCF service and I have it as

Is webHTTPBinding the only one that works with JQuery? I have a similar JQuery call working on my local machine with Visual Studio 2010 in debug mode, but as soon as I publish it to the server it is asking me to use anonymous access on the site which is not an option. I need to be able to transport the credentials. It seems that WCF has changed drastically even between the Beta and the release of VS2010. I am having trouble finding documentation on all but the most common bindings and how to specify security with them.

@Jerry - If you want to use WCF then WebHttpBinding is the only one that really makes sense for REST transport. The problem you're seeing I think is that you can only configure one kind of security with Anonymous being one of the choices. You should be able to use Windows Authentication instead of anonymous though.

I needed to remove the Method="Post" from the list because oddly enough that did not seem to work anymore. Eventhough it was still in the intellicense.. ?

#re: jQuery AJAX calls to a WCF REST Service by
Dan
October 09, 2010 @ 10:57pm

Hi Rick,Best post I found till now on Jquery wrapperbut for me it does not work the stringify of dates I first used ServiceProxy and used firebug to see the result of serializationit was not in the MS Ajax format just enclosed in double quotesI included the json2.js from your modified zip file json2_msdates.zip before the ServiceProxy.jsand also put this.isWcf = true; from this.isWcf = false; what I found in your fileThen tried different date formats with the proxy it still does not workthe code var a = reISO.exec(value); returns null all the times

Then tried to use json2 directly and it is not MS AJAX type of serializationMaybe I did not find your right version of the code? Very confused :)not an expert in Java Script so did not try to understand all codeany help apreciated

Best RegardsDan

#re: jQuery AJAX calls to a WCF REST Service by
Dan
October 10, 2010 @ 11:55am

OK after one night sleep and reading thorugh the libraries and testing I figured it out, never mindThank you for the post Jquery is great

I have a page that uses ServiceProxy.js Version 0.97 - 8/31/10I initially tested it in IE 8 and was working finebut it gives me the message 'JSON' is undefined when I test it with IE 6 and 7the references I have are bellow:

var proxy = new ServiceProxy("/FunStoreTwo/WcfAjaxServices/ManageEmployee.svc/"); proxy.invoke("GetSupervisors", {}, function (result) { for (var i = 0; i < result.length; i++) { var employee = result[i]; var text = employee.FirstName + " " + employee.LastName; var value = employee.UserId; $('#ReportsTo').append($('<option></option>').val(value).html(text)); } }, function (error) { $('#message').text(error.message); } );====================================================================Morevover I had a different page where I used $.ajax({}) instead of ServiceProxy and it works in all brosers. As soon as I add a reference to ServiceProxy.js Version 0.97 - 8/31/10it gets stucked without any message this time (I do not use the library in code only added the reference) these are the only references I added I Have no ideea how to fix it I wonder oif I took an older version of your ServiceProxy.js or it does not work in IE 6 and 7? <script src="../JavaScript/jquery-1.4.1.js" type="text/javascript"></script> <script src="../JavaScript/json2.js" type="text/javascript"></script> <script src="../JavaScript/ServiceProxy.js" type="text/javascript"></script>

I have a page that uses ServiceProxy.js Version 0.97 - 8/31/10I initially tested it in IE 8 and was working finebut it gives me the message 'JSON' is undefined when I test it with IE 6 and 7the references I have are bellow:

var proxy = new ServiceProxy("/FunStoreTwo/WcfAjaxServices/ManageEmployee.svc/"); proxy.invoke("GetSupervisors", {}, function (result) { for (var i = 0; i < result.length; i++) { var employee = result[i]; var text = employee.FirstName + " " + employee.LastName; var value = employee.UserId; $('#ReportsTo').append($('<option></option>').val(value).html(text)); } }, function (error) { $('#message').text(error.message); } );====================================================================Morevover I had a different page where I used $.ajax({}) instead of ServiceProxy and it works in all brosers. As soon as I add a reference to ServiceProxy.js Version 0.97 - 8/31/10it gets stucked without any message this time (I do not use the library in code only added the reference) these are the only references I added I Have no ideea how to fix it I wonder oif I took an older version of your ServiceProxy.js or it does not work in IE 6 and 7? <script src="../JavaScript/jquery-1.4.1.js" type="text/javascript"></script> <script src="../JavaScript/json2.js" type="text/javascript"></script> <script src="../JavaScript/ServiceProxy.js" type="text/javascript"></script>

I had a few problems figuring out how to send dates from my javascript to the WCF services, and I've came up with a pretty neat and simple solution, so I thought it would be a nice idea to share it here. Date objects in javascript have a method called "getTime()" which returns the number of milliseconds since 1970, so we get something like this :

{ date: "\/Date(" + theDate.getTime() + ")\/" }

#re: jQuery AJAX calls to a WCF REST Service by
Ben
December 04, 2010 @ 9:52pm

Rick,

I saw Chris' comment and your response on 2/18/09, and like Chris my objective was to create a client component that could hit a WCF service hosted on a remote server to process data. I was using your example as a guideline, but like Chris I hit a wall when I couldn't hit the WCF service from another site hosted on a different server/port.

Other than setting up a proxy server, are there any other ways around this? Am I utilizing WCF for the incorrect purposes to accomplish my goal? Surely this isn't a unique scenario, so how would you recommend approaching this scenario?

Thanks in advance,

Ben

#re: jQuery AJAX calls to a WCF REST Service by
Ben
December 10, 2010 @ 8:11am

I had a stupid moment, and realized you meant a proxy class and not a proxy server. My issue is that I'm trying to make this solution agnostic of any server-side code. I'm trying to make the call utilizing only client-side code, which is why I'm trying to use jQuery. Thus, I don't want to create a service reference. The only other way I know how to create the proxy class is using svcutil.exe, and that creates code dependent on the .NET framework as far as I know. Is there any way to generate a proxy class just utilizing JavaScript or other client-side code to accomplish my goal?

Ben

#re: jQuery AJAX calls to a WCF REST Service by
Deepankar
February 02, 2011 @ 11:23pm

Firstly, thanks for this great post. I have one problem if i use jquery version 1.5, it throws an error Unknown error occurred in callback. Any idea why this could be happening?

#re: jQuery AJAX calls to a WCF REST Service by
James B.February 09, 2011 @ 10:47pm

@Deepankar,

I had this problem today too, and didn't know what had cause it. Apparently, jQuery completely redid the $.ajax() in version 1.5. And did a good job at being backwards compatible, but there were some things they couldn't do.

He covers what they've changed. If you're using the ServiceProxy.js code provided by Rick, then I had to go in and fix a couple things (I'm using a modified version that handles DateTimes), but it should be the same. And there may be a much better way of doing this, this is just the workaround I found for now.

Find this line:

this.invoke = function (method, params, callback, errorHandler)

Then scroll down to your .ajax(... You'll first notice in version 1.5 they've changed the calling syntax to .ajax(url, settings)...so I simply removed the url from the settings and dropped it into

Hope that helps you out, remember to make sure and use the same success and error functions provided in yours. Also, you might want to make sure your dataFilter is similar to what it was before. But as I said, it will completely ignore dataFilter if your dataType is html, and it appears to not work at all if you don't use a registered parameter.

As Dave said in his posting, "As of jQuery 1.5, using this dataFilter approach for manually controlling deserialization will no longer work if the request’s dataType is set to “json” or even omitted."

#re: jQuery AJAX calls to a WCF REST Service by
Ronnyle
December 20, 2011 @ 3:38am

Hi,

When the service is hosted on another domain the browser first sends an OPTIONS request to validate the Access-Control-Allow-Origin header.However, when I switch to BodyStyle=WebMessageBodyStyle.Wrapped, the server returns 400 errors (and my server method code is never reached).

I found something that might be a bug in the JSON2.js customization. I couldn't get the .parse function to work with a date string that was generated by the .stringify function. So this date string:

2011-04-11T21:44:14.960Z

Was getting split like by this line of code:

var matches = str.split(/[-,:,T,Z]/);

and winding up with the period between seconds and milliseconds still there, which doesn't work for the conversion to a javascript date variable using the Date.UTC function. Also, after the .join there was still an extra comma at the end. So I also added a .pop to the array if the last piece is an empty string to avoid this. Here is my modified code that works for me:

@zege - nope - cross domain calls are not allowed using AJAX. best you can do is JSONP which is not directly supported by WCF REST.

#re: jQuery AJAX calls to a WCF REST Service by
Pullet
January 15, 2013 @ 10:37am

hi

how can i use jquery to call wcf service using custom userNamePasswordValidationMode. i was able to call using asp.net client program but could not do it using jquery. I kept System.Web.Script.Services.ScriptService for service class to enable it to be called from script. I am using wsHttpBinding binding. I want to call this service from jquery to authenticate and fetch data and it should be cross domain calls using jsonp.