Converting no-code Sandboxed Solutions to Apps for SharePoint

SharePoint 2013 introduces the new App Model for deploying customizations. Find out what you need to take into account to convert your existing no-code Sandboxed Solutions to the new Apps for SharePoint.

No-code Sandboxed Solutions

Sandboxed Solutions were released together with SharePoint 2010 and were supposed to be the answer to quite a few challenges originating from deploying code using Farm Solutions, but also to allow deploying customizations to SharePoint Online. Unfortunately, soon after the release of this new model, it turned out that executing code in an isolated process wasn’t that much of a good idea. As a result Sandboxed Solutions never got adopted at the scale assumed initially.

Although Sandboxed Solutions haven’t become the replacement for Farm Solutions, they turned out to be of added value after all. While deploying code with Sandboxed Solutions was too limiting, Sandboxed Solutions appeared to be a good choice for deploying declarative artifacts such as Content Types, Web Templates or Branding and so the concept of no-code Sandboxed Solutions saw the daylight.

For quite a few years no-code Sandboxed Solutions have been used to deploy customizations and extensions for the SharePoint platform. Even though the model is limited comparing to Farm Solutions, it allows for building and distributing rich solutions including Web Templates, List Definitions or Ribbon extensions with Page Components to name a few.

SharePoint 2013 – the era of apps

With its release SharePoint 2013 introduced a new model for deploying SharePoint customizations and extensions called App Model. In no way is the App Model a replacement for Sandboxed Solutions as it’s build around a different paradigm. Nevertheless it is the preferred approach for thinking about and designing extensions for the standard SharePoint capabilities.

No-code Sandboxed Solutions are still supported and valid for many different scenarios. With the shift towards the App Model it is however worth considering to provide a more consistent experience and convert existing no-code Sandboxed Solutions to Apps for SharePoint where it makes sense.

Converting no-code Sandboxed Solutions to Apps for SharePoint

The process of converting a no-code Sandboxed Solution to an App for SharePoint is not without considerations. Although the exact steps will vary depending on the contents of your no-code Sandboxed Solution, there are a few things that you are very likely to stumble upon every time you convert a no-code Sandboxed Solution to an App for SharePoint.

To illustrate the process of converting a no-code Sandboxed Solution to an App for SharePoint I will use the Mavention Insert Table of Contents solution that I converted to an App for SharePoint recently.

Step 1: Analyzing the no-code Sandboxed Solution

The Mavention Insert Table of Contents no-code Sandboxed Solution consists of the following components:

  • Custom Action that registers a custom Ribbon button
  • Page Component that interacts with Rich Text Editor
  • Page Component Loader script
  • Custom Action that registers the Page Component Loader script with the Script Link
  • Module that provisions Page Component and Page Component Loader script files to Style Library
  • Site Collection Feature that provisions the script files to the Style Library and activates the Custom Actions

Mavention Insert Table of Contents solution in Visual Studio

After installing and activating the Solution in the Site Collection, the Site Collection Feature provided with the Solution becomes available in the list of Site Collection Features. Enabling the Feature causes script files to be provisioned to the Style Library and activates the Custom Actions in the Site Collection. One of the Custom Action adds a custom button to the Ribbon which is enabled only when a Rich Text Editor is active on a page. This is controlled by the Page Component loaded by its loader script activated by another Custom Action. Whenever the Ribbon button is clicked, the contents of the active Rich Text Editor are analyzed, the table of contents is built and added at the cursor position in the Rich Text Editor. All of this is orchestrated by the Page Component.

Now that we know which components we have and how they work, we can start remapping them to the App Model and its capabilities.

Step 2: Recomposing the solution to fit the App Model

No-code Sandboxed Solutions contain no server-side code and are therefore perfect candidates to be converted to SharePoint-hosted apps. Depending on the contents of the no-code Sandboxed Solutions a SharePoint-hosted app might or might not be the best fit, but it’s good to start with it as SharePoint-hosted apps are the easiest to build and deliver to customers.

One of the differences between Apps for SharePoint and Sandboxed Solutions is that whereas Sandboxed Solutions are deployed to the Site Collection, the App, along with all its contents, is deployed to its own Web. While this model perfectly fits the purpose of an isolated and task-oriented solution, it doesn’t support integrating the solution with the parent Site Collection. In order to provide the integration that we need, the resources must be provisioned and activated on the parent Site Collection.

Following is the overview of all components and how they fit into the SharePoint-hosted app.

Custom Actions that register Ribbon customizations and scripts can be registered programmatically using the Site.userCustomActions property for Site Collection-scoped customizations and Web.userCustomActions property for Site-scoped customizations.

Scripts registered in the userCustomActions property must be located within the Site Collection but outside of the App Web.

Page Component that interacts with the Rich Text Editor and Page Component Loader script

Both scripts remain as-is.

Module that provisions Page Component and Page Component Loader script files to Style Library

Unfortunately Apps for SharePoint contain no way to declaratively provision app files to the Host Web or Site Collection. The only way to provision those files to the Host Site Collection is programmatically using the JavaScript Object Model or REST API.

Site Collection Feature that provisions the script files to the Style Library and activates the Custom Actions

There is no corresponding mechanism available in Apps for SharePoint. The one-time configuration process of deploying resources to the Host Site Collection and registering the custom actions has to be covered for programmatically and once the configuration has been completed the state should be persisted to avoid the configuration process from executing again.

As all resources are copied and registered manually, they also need to be cleaned up manually.

Step 3: Building the App

The app should have the following flow: after starting the app, it should check whether it has been enabled on the Host Site Collection or not. Depending on its current state it should allow the user to either enable or disable it.

Enabling the app starts with copying the resources files (Page Component and Page Component loader script files). As those files are copied to a folder inside Style Library the app needs to ensure that the target folder exists and create it if necessary. After the resource files have been copied, the next step is to register the custom actions with the Host Site Collection. The last step is to persist the fact that the app has been enabled. One way of doing it is to store a custom property in the property bag of the App Web where it can be easily retrieved from by the app on each start to check the app state.

The process of disabling the app is reversed. The app starts with removing the Custom Actions. Next it deletes the resource files and folders. Finally it changes the app state to disabled in the property bag of the App Web.

Mavention Insert Table of Contents App in Visual Studio


Although the process of enabling and disabling the App might seem self-explanatory there are surprisingly quite a few things to take into account to ensure that everything will work as expected.

Ensuring for folders

When copying resource files to the Host Site Collection the target path must exist or the copy process will fail. If you have multiple solutions, you might be using a folder structure such as Style Library/Contoso/Solution-X to have resource files of all your solutions in a single location. Unfortunately this adds complexity as you need to check for the existence of the whole folder hierarchy and create each one separately if necessary. Additionally, when disabling the app you need to remove the app-specific folder, but you should remove the company folder only if there are no other apps using it. Given that you need to do all of that yourself, you might remove the company folder from the hierarchy and create the app-specific folder directly in the Style Library just to keep things easier.

Uploading files

Uploading files by itself isn’t that complex. It’s the versioning of those files that you need to take into account. If you want your app to work directly after enabling it, you need to ensure that all resource files are not only copied but also checked in and published (and approved if applicable). What complicates this process is the fact that if you are updating your app, the old resource files might be checked out or checked in as draft and you have to plan for all those states when provisioning new versions of those files for the copy process to succeed.

Configuring Custom Actions

Configuring Custom Actions is relatively straight-forward comparing to other steps of enabling the app. One thing that you should remember is that all scripts must be present in the Host Site Collection outside of the App Web for the Custom Actions to work. If you try to deploy a Custom Action with a reference to a script located in your App Web, the next time you navigate to your Site you will see nothing but an empty screen and will need to remove the broken Custom Action using Client Side Object Model to be able to use your Site Collection again.

In order to be able to configure a Custom Action on the Host Web or Host Site Collection your app has to have Full Control permissions on the corresponding scope. Unfortunately this will make it impossible for you to publish your app in the Office Store as apps that require Full Control permissions at any scope are not allowed in Office Store.


Given that you need to implement the process of enabling an app on the Host Site Collection yourself, it is up to you to choose whether you want to use the REST API or the JavaScript Object Model to perform all the necessary actions.

In general many find REST easier to read and follow than JSOM. On the other hand REST is chatty and using JSOM can help you batch your operation limiting the number of requests. Unfortunately there is more to choosing either approach than a personal preference or performance. Currently the REST API and JSOM don’t offer the same capabilities and there are operations that simply cannot be done using the REST API. For example the only way to set a value of a property in the property bag of a Web is to use JSOM. Even though the REST API might be your preferred approach, keep in mind that currently certain things can be accomplished only through JSOM.

Error handling

Using the different REST API endpoints and JSOM, particularly in combination with cross-site requests required to communicate with the Host Site Collection, you will find out that different pieces of the API report errors in different ways. This makes it challenging to build a consistent error handling mechanism for your app and you have to have a closer look at the different responses of the API that you are working with, particularly in scenarios where an error isn’t necessarily a bad thing (ie. checking if a file already exists).

Other artifacts

Mavention Insert Table of Contents is a good example of a no-code Sandboxed Solution but it definitely doesn’t use all of the possible artifacts that could be packaged in a no-code Sandboxed Solution. Depending on the contents of your solution you might find out that you need a different type of App for SharePoint or you simply cannot fit it into the App Model at all. As I mentioned before, the App Model is designed based on a different paradigm, where apps are task-oriented and isolated and don’t integrate into the user experience the way Farm or Sandboxed Solutions do. There is nothing wrong in admitting that the App Model won’t work for the particular solution, but the real challenge is to try to figure out how the particular business problem could be solved using the App Model.

Is it worth it?

You have just gone step-by-step through the process of converting a perfectly okay no-code Sandboxed Solution to a SharePoint-hosted App. Nothing changed from the functional point of view and even though the new solution is an App for SharePoint it cannot be published in the Office Store due to the Full Control permissions necessary to register the Custom Actions. Given the complexity and effort involved: was it worth it?

Although the App Model has been around since the release of SharePoint 2013 it is still relatively new and not that many apps have been built yet. Still, building SharePoint customizations and extensions as apps comes with benefits even if you take into account the effort you have to go through to build your app.

If you’re converting a no-code Sandboxed Solution to a SharePoint-hosted App there are quite a few steps that you have to go through to enable your app on the Host Site Collection. Currently all of those have to be covered for manually, but the odds are high that in the future helpers libraries will be available in the community to make the process less verbose and to allow you to focus on the solution rather than its foundations.

No-code Sandboxed Solutions are okay for now, but given the direction that SharePoint extensibility is heading it’s a fair thing to say that in the future things will look different. It is a good time now to start thinking differently about designing and distributing SharePoint customizations and learning the new skillset applicable to the App Model.

Others found also helpful: