Using SharePoint’s Imaging Web Service to access Publishing Images

I spent a fair amount of time yesterday trying to access the images in the Images list (also known as Publishing Images) of a SharePoint site using the SOAP-based Imaging web service. Every time it failed, usually with an uninformative error message.

Finally, I used cURL to send the SOAP requests so that I could see every last detail of the transaction. The SOAP response was pretty clear at that point:

The list PublishingImages is not found

or

The list Images is not found

I tried other Picture Libraries on the site, and that worked fine. That’s when it dawned on me: the SharePoint Images (or PublishingImages) list is a Document Library, not a Picture Library. That makes absolutely no sense whatsoever, but fine, it wouldn’t be the first time I’ve run into something nonsensical in SharePoint.

I was hoping to use the download method of the Imaging web service. I don’t have an alternative solution at this time, but I hope to find one soon using one of the other SharePoint web services.

JSONP and Sencha Touch

I was recently trying to get a Sencha Touch demo up-and-running, but my callback functions after requests for JSON data never ran, and Firefox would throw errors along the lines of “invalid label.” I didn’t understand why–until I read more about JSONP.

JSONP prefixes your JSON response with a function name, which runs when the response is retrieved. It’s a way of handling the data without a listener.

This means that your JSONP provider needs to detect a JSONP parameter, and then wrap or “pad” the response within the specified parameter value.

For Sencha Touch, the JSON returned should be wrapped in Ext.util.JSONP.callback();. If your JSON looks like this:

{"results":[{"name":"Chris"},{"name","Harry"}]}

then your JSONP should look like this:

Ext.util.JSONP.callback({"results":[{"name":"Chris"},{"name","Harry"}]});

Not that you should hard-code that function name anywhere in your JSON output–web-based APIs and services should pick up the function from your request and wrap the JSON for you. For example, the twitter search API accepts a callback querystring parameter.

http://search.twitter.com/search.json?q=fakecriterions&callback=myCallbackFunction

would wrap the JSON response inside

myCallbackFunction();

I ignored the extra letter in the acronym at my own peril–I figured it was just a trivial variation on JSON (which it is) that wouldn’t make any difference in how it was handled (but it does).