Playing in the Sand
Those of you who have worked with Sandboxed Solutions know the give and take they represent: they provide solace and security to the administrators by insuring that runaway code doesn’t kill a server, but at the same time they can handcuff a developer in their quest to meet the customer’s needs.
I recently worked on a project that needed to provide a web service from within SharePoint in a way that was sandbox-friendly. A coworker of mine found a great link on creating custom web services within a sandbox: Sandboxed Web Service – BillGr’s Blog – Site Home – MSDN Blogs. I’ve done a bit of research to build upon the ideas presented in this article.
The example provided in the link above used a StringBuilder to emit JSON. I like JSON, but I also like XML, especially when I want to use XSLT. I also like using DataContracts. Here are some changes to the example provided in the blog referenced above showing a simple DataContract. This has been tested not only in a sandboxed solution, but also in SharePoint Online. To show that it is possible to read post data, we also return a POSTed request body.
In order to produce the desired output, I provided an override to the Render() method in the Web Part. In this simple example I put the list items into an array of Task objects and output the data as XML or JSON. Note that in lieu of custom XML, you can emit SPListItemCollection.Xml, but in many cases you want more control of what you are providing and it may not be list data at all (not to mention that the XML is quite bloated).
An example of the rendered XML is below (newlines and white space added for clarity). Note that when using a browser to call the web service manually, you may have to choose to “view source” to see the output because of the limitation that we are unable to specify the Content-Type in the response header. I used the REST Client for Firefox so I could POST some data and easily set the Accept request header.
Using the JSON option, we get this output:
Starting with the sample page referenced in the original blog post, I added a few more methods to test in different ways (note that I didn’t modify the existing method that was already in the code).
In addition to the above script, I added some markup for buttons:
Testing my new code produced the following results (note that I’m using a Tasks list because I’m expecting there to be a Status in the returned results):
Building Castles In The Sand
While there are still possible limitations to this (particularly related to the fact that we cannot manipulate the Response-Type in the HTTP Response Header), this is an interesting and exciting technique for implementing web services in a Sandboxed Solution.