Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Custom Webservices with SharePoint Online for Office 365

5.00/5 (1 vote)
13 Aug 2012CPOL5 min read 72.7K   856  
Development of webservices using sandbox solutions

Introduction

Office 365 is the next-generation cloud productivity service that delivers important functionalities for business, investing less than on-premise solution.

It brings together 2010 editions of Exchange Online, Lync Online, Office tools, and SharePoint Online as a cloud service for organizations of all sizes.

In particular SharePoint Online provides a solid business collaboration platform on which developers can build solutions by using standard development tools such as Microsoft SharePoint Designer 2010 and Microsoft Visual Studio 2010. However, from a developer point of view SharePoint Online puts many constraints and we need to modify the standard development pattern.

We can only deploy sandboxed solutions that create a secured wrapper around webparts and other elements with some limitation about SharePoint Object Model. They cannot absolutely modify or add any file to the file system and all our code runs in separate worker processes and not in w3wp.exe. This kind of solutions has pros (it doesn't require Application Pool Recycling!!) and cons (first of all it doesn't support Security Elevation). This article deals with the issues that forbid us to deploy any WCF or "old" ASMX service using SharePoint Sandbox solutions. The suggested solution overcomes this limitation, simulating a webservice with a simple ASPX page that returns data in JSON format rather than standard text/html.

In details we create:
  • a sandbox webpart to encapsulate business logic of the service
  • a custom master page to eliminate needless content in the output response
  • a web page to simulate the webservice endpoint
  • a web page to consume the service and show a typical use of it
Let's go!

Create Sandboxed webpart

It is not the focus of this article to create a complex business logic or show the capability of the SharePoint Server-Side Object Model, but try to explain a different approach to consume SharePoint data.

In the demo we are going to instantiate this simple object with some information about subsites:

C#
public class Stats
{
    public List<Site> Sites { get; set; }
}

public class Site
{
    public string Title { get; set; }
    public int ListsCount { get; set; }
}

The operation is simple using the SharePoint Object Model server-side: we do a for...each iteration to get the title and the number of lists in the site; the same operation in a client-side script could be more complex because of asynchronous calls. For any details on these steps, I suggest to see the source code in the attachment (WSWebpart feature)

After we fill the properties of the object, we have to serialize it and create the JSON string to send back to the client. There are many way to obtain this, the most simple is to use JavaScriptSerializer, included in .NET Framework 3.5 (in the System.Web.Extensions.dll assembly)

C#
Stats stats = new Stats();

...

JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(stats);

Custom Masterpage

The master page must be very simple in order to return only the raw result in JSON format. So we can create a master page with only one placeholder:

ASP.NET
<%@ Master language="C#" %>
<asp:ContentPlaceHolder id="PlaceHolderMain" runat="server">
</asp:ContentPlaceHolder>

In this way we have removed all unisexual information such as JavaScript, CSS, and other contents, obtaining a clean page.

Simple Service Page

Now we can add the custom sandbox webpart with the implementation of the service in a new page, forcing to use our master page. To achieve this, we can use a new control included in the SharePoint 2010 framework: SPUserCodeWebPart. The page on MSDN doesn't contain any example, however the required properties to reference univocally the webpart are:

  • AssemblyFullName: The full name of the user code Web Part assembly (e.g. WebServiceSandbox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bf13a1a9ef2c3dc4)
  • SolutionId: The ID of the solution
  • TypeFullName: The full name of the sandboxed solution Web Part type
To simplify the process we can use the replaceable parameters included in Visual Studio 2010 solutions. In particular we have $SharePoint.Project.AssemblyFullName$ for the AssemblyFullName and $SharePoint.Package.Id$ for the SolutionId. Instead for the TypeFullName there isn't any specific variable, but as suggested in this detailed MSDN article and in below comments, we can use the generic parameters $SharePoint.Type.<GUID>.FullName$ replacing <GUID> with that added in the WebPart declaration. In the sample the code is:
XML
<WebPartPages:SPUserCodeWebPart 
   runat="server" 
   Description="ServiceWP" 
   Title="ServiceWP" 
   AssemblyFullName="$SharePoint.Project.AssemblyFullName$" 
   SolutionId="$SharePoint.Package.Id$" 
   ID="servicewp" 
   TypeFullName="$SharePoint.Type.a2548058-31d8-4364-8043-1ea3a1eb21e1.FullName$" >
</WebPartPages:SPUserCodeWebPart>

Moreover in the declaration of the page we must change the URL of the MasterPage in order to reference the custom one.

ASP.NET
<%@ Page language="C#" MasterPageFile="~site/_catalogs/masterpage/WSMasterPage.master" ... %>

The ~site parameter is required if the site collection isn't the root of the Web Application (e.g., http://dev/sites/wstest).

After we have created the page, we have to create a feature to deploy this in the SharePoint Document Library. This can be achieved using a module as this (in the solution it is in the WSServicePage folder):

XML
<Module Name="WSServicePage">
   <File Path="WSServicePage\WSServicePage.aspx" Url="Documents/WSServicePage.aspx" />
</Module>

Consume webservice with jQuery

The last step is create a page consuming the service; it is quite simple, there is a button that calls our custom webservice and displays the well-formed result in a div panel (with id #list)

In order to make the development easy, we use AJAX functionalities of the jQuery framework and we can insert the script in the OOTB SharePoint Content Editor Webpart or add it directly in the source code of the page.

JavaScript
$(function () {
   $.getJSON("/Documents/WSServicePage.aspx", function(data) {
      $.each(data.Sites, function(i,s) {
        var txt = 'Site ' + s.Title + ' has ' + s.ListsCount + ' lists' ;
        $('<li>').text(txt).appendTo($('#list'));
      });
  });
});

Conclusion

In this article we have analyzed a way to overcome a Office 365 limitation: sandbox solutions can be difficult to use at times because of all the limitations, however there are many new techniques that allow developers to handle these issues exploring new approaches and solutions.

This approach doesn't want to replace other valid and totally supported solutions such as JavaScript Client Object Model (JSOM), SPServices, or simple calls to SharePoint REST services, instead it just aims to suggest a way to reuse source code developed with a server-side object model or simply for users that haven't good practice with JavaScript. Moreover I find this approach very useful when we need nested queries using SharePoint context that require many asynchronous calls using JSOM script.

About the sources

In the solution there are four features:
  1. WSWebpart with the webpart with the logic of service
  2. WSMasterPage with the simple masterpage
  3. WSService with the page containing Webpart
  4. WSConsumer with the page that calls the "service"
327919/Solution.png

History

  • 10th February, 2012: Initial version.
  • 14th February, 2012: Updated source code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)