Calling SharePoint Web Services from Javascript

April 20, 2007

I’m on a mission. And that mission is to build SharePoint apps without dropping code on the server. Why would anyone want to do this? Well, in many enterprise or hosted environments you don’t have the ability to drop DLLs into a shared SharePoint environment. This has often limited the types of applications we can build to out of the box features or SharePoint designer. But with some Javascript and the WSS web services, we can build a more complex app all with AJAXy goodness.

This code sample uses the Prototype Javascript library. When you see Ajax.Request, that’s using prototype’s Ajax framework. The great thing about prototype is that everything is cross-browser compatible.

First we need some code that formats a simple SOAP envelope. SOAP is the required protocol for communicating with the SharePoint web service.


var Soap = {
  createEnvelope: function(action, ns, parameters)
  {
    var soap = '<?xml version="1.0" encoding="utf-8"?>
        <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
        <soap12:Body>';
    soap += '<' + action + ' xmlns="' + ns + '">';
    soap += Soap.__parseParameters(parameters);
    soap += '</' + action + '></soap12:Body></soap12:Envelope>';
    return soap;
  },

  __parseParameters: function(parameters)
  {
    var params = "";
    if (typeof parameters == 'object')
    {
      // check if we were provided an array or an object
      if (typeof parameters.push == 'function')
      {
        for (var i = 0, length = parameters.length; i < length; i += 2)
        {
          params += "<" + parameters[i] + ">" + parameters[i+1] +
              "</" + parameters[i] + ">";
        }
      }
      else
      {
        $H(parameters).each(
          function(pair)
          {
            params += "<" + pair.key + ">" + pair.value + "</" + pair.key + ">";
          });
      }
    }
    return params;
  }
}

Okay, so now we can make a SOAP envelope as simple as this:

var mySoap = Soap.createEnvelope(
  "MyAction",
  "http://schemas.microsoft.com/sharepoint/soap/",
  { param1: "value", param2: "value" });

Simple enough. Now let’s call a SharePoint web service. We’ll use the Lists web service and create a new list item. The UpdateListItems method allows us to pass in some XML defining the items to create. So first I’m going to build that XML.

var batch = '
  <Batch OnError="Continue">
    <Method ID="1" Cmd="New">
      <Field Name="ID">New</Field>
      <Field Name="Title">Hello World</Field>
    </Method>
  </Batch>';

Next we’ll call the web service using the Ajax.Request object:

// build parameter object
var parameters =
{
  listName: "My List",
  updates: batch       // xml created earlier
}

// create soap envelope
var soap = Soap.createEnvelope(
  "UpdateListItems",
  "http://schemas.microsoft.com/sharepoint/soap/",
  parameters);

// call web service
new Ajax.Request(
  "http://myserver/mysite/_vti_bin/lists.asmx",
  {
    method: "post",
    contentType: "application/soap+xml",
    postBody: soap,
    onSuccess: function(transoprt) { alert("Success: " + transport.responseText); },
    onFailure: function(transport) { alert("Error: " + transport.responseText); }
  });

If all goes according to plan, I should have a new list item with the title of “Hello World” in the list called “My List”.

A couple of points about the javascript above:

  1. It’s certainly not the greatest Javascript in the world. I plan to clean it up and hopefully release a Javascript library for working with all of SharePoint’s web services.
  2. The user’s browser must already be authenticated for this to work. Prototype doesn’t have a way to pass credentials to the web service so make sure you run this from a machine joined to the same domain as the sharepoint site. Ideally this is running within a sharepoint site so that should take care of the authentication problem.
  3. FireFox has an issue because it doesn’t pass domain credentials automatically. This makes debugging hard from your workstation, but if it’s running on a SharePoint site where the user has already authenticated, it works fine.
  4. I cheat in the example above and break strings onto multiple lines. That’s for the purpose of formatting only. If you copy and paste this code directly it won’t work.

You can download the code here: wsswebservice.js.

Advertisements

7 Responses to “Calling SharePoint Web Services from Javascript”

  1. Tom Says:

    Can’t download the js file – can you fix pls. thx

  2. glen Says:

    Oops – sorry. Fixed

  3. Jeroen Says:

    Great Solution!

    I’ll use this for my Vista Sidebar gadget 🙂

    Cheers,

    Jeroen

  4. Boris Says:

    I like your mission! And the script also works super!

  5. Divine Says:

    Can you please explain the point no 2:
    “The user’s browser must already be authenticated for this to work. Prototype doesn’t have a way to pass credentials to the web service so make sure you run this from a machine joined to the same domain as the sharepoint site. Ideally this is running within a sharepoint site so that should take care of the authentication problem”

    How do u run the javascript from within the sharepoint site?

  6. Shaun Says:

    I am trying to implement your code however I am getting an error. It’s a soap error and the fault string is:

    “Unable to handle request without a valid action parameter. Please supply a valid soap action”

    I uploaded the prototype.js file and copied the code from your js file into my page. I am calling the createListItem function from a button. I created a list and updated the list name and the Ajax.Request url. Is there anything else I need to be doing? Thanks in advance!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: