Enabling JSON serialization and jQuery posts for SharePoint web services
While making the finishing touches to a new web part I'm publishing here shortly, I found myself wanting to make JSON enabled jQuery AJAX requests to custom .asmx services I'd deploy to the _vti_bin service root of my SharePoint portal. The incentive is simple; jQuery is quite nice for quickly typing up dynamic UIs, and by connecting that to a service backend, I can do even more fun stuff (which will become clear in my next post). An alternative to jQuery would be to stick with ASP.NET Ajax, but to be honest, I find that a lot less comfortable, when my code is mostly client side (javascript), and I'm deploying it all to SharePoint.
The overhead of using ASP.NET ajax for simple stuff like this is another story altogether, and while I don't have any specific numbers, I'm sure you'd see quite a bit more data on the wire (large scripts, xml encapsulation, etc.), compared to simple jQuery ajax post requests with JSON for data encapsulation. If you're interested in that part, throw in a few google searches - I'm sure it's been thoroughly covered elsewhere.
Anyhoo, the point here is jQuery/JSON and whatnot, so if that's what you're after; keep reading.
What I soon discovered after attempting to make simple $.ajax calls from jQuery, was that HttpPost isn't enabled for the _vti_bin folder. Trying to call /_vti_bin/MyService.asmx/SomeMethod will result in some less-than-intuitive error page (especially when seen through the deserialized error callback of jQuery's .ajax()). This is essentially caused by the default _vti_bin config not allowing HttpPost service calls. Your options are either to change the configuration, which I'll soon outline, or make SOAP envelope calls. I find the latter fairly tedious, having to construct fairly large XML structures in strings, rather than just calling an url like that of SomeMethod above.
Fixing the config, to allow simple service call urls, is pretty simple. Open the web.config from your "Web Server Extensions\12\ISAPI" folder, and flick the "remove" keyword of HttpPost to "add". The system.web configuration should look like:<system.web>
<webServices>
<protocols>
<remove name="HttpGet" />
<add name="HttpPost" />
<remove name="HttpPostLocalhost" />
<add name="Documentation" />
</protocols>
</webServices>
<customErrors mode="On"/>
</system.web>
At this point, you'll be able to call the web services through HTTP Post requests, even from jQuery, such as:$.ajax({
type: 'POST',
url: '/_vti_bin/MyService.asmx/SomeMethod',
data: '{}',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(msg) { alert(msg.d); },
error: function(xhr, msg){ alert(msg + '\n' + xhr.responseText); }
});
Still there's the case of JSON, however, so the JavaScript above would still trigger the error callback, with your web service's return value encapsulated in XML. Should you wish to use XML for data transport, you'd be all set now.
To enable JSON, you'll first of all need the .NET 3.5 framework installed on the server. If you haven't already done this (2008 should have it pre-installed), go do so now. Once that's in place, there's a few quick changes which need to be made to your web application's web.config - not dissimilar to the general steps to make ASP.NET Ajax working.
Within <system.web><httphandlers> tag, add the following line, right after the initial <remove>:<add verb="POST" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
Within the <safecontrols> tag, add the following at the bottom:<SafeControl Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" Namespace="System.Web.UI" TypeName="*" Safe="True" />
This should pretty much be all you need, and you should be all set for using jQuery and JSON to query your own custom _vti_bin deplyed services, from web parts, pages and so forth.
My next post will provide an example of this combination, calling a custom .asmx service from jQuery, with JSON serialization for parameters / return value, neatly wrapped up in a WSP.

0 comments:
Post a Comment