Calling SharePoint web services using jQuery

I needed to update a SharePoint list item directly on client side in a classic SharePoint list form. I found this blog who explains very well how to do it by using Prototype but I was already using jQuery and didn’t want to add another javascript framework to my solution. Sure this is very easily portable to jQuery but I wanted a cleaner solution.

I found this: jQuery SOAP Client, a jQuery plug-in (it’s really an add-on because it doesn’t use jQuery extension mechanism) who was looking very promising. So I started to code…

I was going to call the UpdateListItems of the list web service (http://server/_vti_bin/lists.asmx). This method requires two arguments: listName and updates. Updates are the CAML commands describing the changes to the list and looks like this:

<Batch OnError="Continue">
    <Method ID="1" Cmd="Update">
       <Field Name="ID">1</Field>
       <Field Name="Title">updated title</Field>
    </Method>
</Batch>

I think that’s pretty readable: we want to change the Title of the element with the ID=1 to “updated title”.

Next: the javascript code using jQuery SOAP Client:

var wsMethod = "UpdateListItems";
var soapNs = "http://schemas.microsoft.com/sharepoint/soap/";

var soapBody = new SOAPObject(wsMethod);
soapBody.ns = soapNs;
soapBody.appendChild(new SOAPObject("listName")).val("list1");
soapBody.appendChild(new SOAPObject("updates")).val(batch);

var sr = new SOAPRequest(soapNs + wsMethod, soapBody);

SOAPClient.Proxy = "http://server/_vti_bin/lists.asmx";

SOAPClient.SendRequest(sr, processResponse);

For this to work it needs to be executed from an already authenticated SharePoint web page. Internet Explorer automatically passes the credentials with the XHR call. You could pass the credentials in the jQuery call but I wouldn’t do that if I where you.

Well, this didn’t work… I was getting some generic SharePoint error page, not very useful for debugging so I fired up Fiddler2.
I found out that the response was a HTTP error code 415 – Unsupported Media Type. I noticed some differences between the SOAP request created by jQuery SOAP Client and the SOAP code expected by the service and modified the plug-in accordingly. But I was still getting the same error.

And then I saw it: the Content-Type sent was application/x-www-form-urlencoded, text/xml; charset= "utf-8"; Thing is when you make an AJAX call with jQuery it automatically ads application/x-www-form-urlencoded content-type if no content-type is specified. But jQuery SOAP Client added the content-type not by using jQuery but directly into the XmlHttpRequest object:

$.ajax({
	 type: "POST",
	 url: SOAPClient.Proxy,
	 dataType: "xml",
	 processData: false,
	 data: content,
	 complete: getResponse,
	 beforeSend: function(req) {
		req.setRequestHeader("Method", "POST");
		req.setRequestHeader("Content-Length", SOAPClient.ContentLength);
		req.setRequestHeader("Content-Type", SOAPClient.ContentType + "; charset=\"" + SOAPClient.CharSet + "\"");
		req.setRequestHeader("SOAPServer", SOAPClient.SOAPServer);
		req.setRequestHeader("SOAPAction", soapReq.Action);
	 }
});

Fixing that was simple and… it worked!!!

$.ajax({
	 type: "POST",
	 url: SOAPClient.Proxy,
	 dataType: "xml",
	 processData: false,
	 data: content,
	 contentType : SOAPClient.ContentType + "; charset=\"" + SOAPClient.CharSet + "\"",
	 complete: getResponse,
	 beforeSend: function(req) {
		req.setRequestHeader("Method", "POST");
		req.setRequestHeader("Content-Length", SOAPClient.ContentLength);
		req.setRequestHeader("SOAPServer", SOAPClient.SOAPServer);
		req.setRequestHeader("SOAPAction", soapReq.Action);
	 }
});

You can download the source code here

This entry was posted in AJAX, Sharepoint, jQuery. Bookmark the permalink.

Comments are closed.