Continuing my little diversion into SharePoint “host web apps” or “Full Control apps” (i.e. apps which provision to the host web) within my larger series about apps, today I want to look at provisioning fields (site columns) and content types – but provisioning them into the host web, rather than the app web. Just to explain where we are in my overall series, here’s the evolving table of contents:
- SharePoint 2013 apps – architecture, capability and UX considerations
- Getting started – creating lists, content types, fields etc. within a SharePoint app (provisioning)
- Working with data in the app web, and why you should
- Access end-user data (in the host web) from a SharePoint 2013 app
- Rolling out SharePoint 2013 apps to the enterprise - tenant scope and PowerShell installs
- Azure is the new SharePoint ‘_layouts’ directory
- “Host web apps” – provisioning files (e.g. master pages) to the host web
- “Host web apps” – provisioning fields and content types [this article]
- Deploying SP2013 provider-hosted apps/Remote Event Receivers to Azure Websites (for Office 365 apps)
- Working with web parts within a SharePoint app
The idea of provisioning fields and content types to the host web are important techniques for host web apps - since if we can have an app which creates fields/content types AND can provision files to the host web (using the techniques in my previous article), then we could use an app to deliver the building blocks for typical SharePoint collaboration solutions.
As ever, this will only be possible if:
- The app requests (and is granted) “Full Control” permission of the host web
- Note this means it cannot be sold via the Office/SharePoint Store (see Validation checklist for apps for Office and SharePoint). But it can be deployed internally through the organization’s App Catalog..
- CSOM code is used for provisioning, rather than standard Feature XML
N.B. At this point, you might be interested in the “Should you do this? Deciding between host web apps/sandbox/farm..” section of the previous article.
Challenges when provisioning fields and content types to the host web
I think if we’re going to build apps like this, then we’d probably want some helper methods which can:
- Provision fields (as site columns)
- Provision content types
- Add fields to content types
As before, I’m using JSOM code in the default page of my SharePoint-hosted app – this could be adapted to something different if required. Some challenges I noticed were:
- It doesn’t seem possible to be able to create a content type with a specific content type ID with CSOM – perhaps I overlooked something, but in any case it does seem possible to obtain it with a later call
- It seems you have to re-fetch any fields and content types after initial provisioning in order to use them – you cannot use the objects returned from CSOM/JSOM methods. If you try this, it seems CSOM gives you cut-down objects which don’t have some members, and this causes errors like this:
How to: provision fields and content types to the host web
The code below is a little bit spaghetti-fied, due to it needing a chain of CSOM commands – an improvement would be to move the code over to using promises and jQuery’s deferred object. As it is, some of our methods need to be called in success callbacks since, for example, before we can add the field to the content type we need both to exist.
It also took me a while to realize that I needed a reference to the actual SP.Field to be able to use SP.FieldLinkCreationInformation, and that whilst I could probably obtain my content type’s ID after creation and then fetch it using this ID, simply iterating all the content types and finding mine resulted in the same number of CSOM calls. Anyway, here’s the code I used:
Running the app
Once our app is built and we add it to a site, the person adding has to accept the Full Control permission request:
..and just like last time, my app has some sample UI which confirms the steps which have been taken:
Now when we go back to the host web, we see that our field and content type have indeed been provisioned:
..and the field has been added to the content type, so it is ready to use:
Download the code
You can download the full Visual Studio project with the code I used for these two articles from here – download the code.